-
Notifications
You must be signed in to change notification settings - Fork 4
Add ProcessInfo2 call #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,13 @@ | ||
package dotnetdiag | ||
|
||
import ( | ||
"bytes" | ||
"encoding/binary" | ||
"fmt" | ||
"io" | ||
"net" | ||
|
||
"github.com/pyroscope-io/dotnetdiag/nettrace" | ||
) | ||
|
||
// Client implement Diagnostic IPC Protocol client. | ||
|
@@ -58,8 +63,8 @@ type CollectTracingConfig struct { | |
// NewClient creates a new Diagnostic IPC Protocol client for the transport | ||
// specified - on Unix/Linux based platforms, a Unix Domain Socket will be used, and | ||
// on Windows, a Named Pipe will be used: | ||
// - /tmp/dotnet-diagnostic-{%d:PID}-{%llu:disambiguation key}-socket (Linux/MacOS) | ||
// - \\.\pipe\dotnet-diagnostic-{%d:PID} (Windows) | ||
// - /tmp/dotnet-diagnostic-{%d:PID}-{%llu:disambiguation key}-socket (Linux/MacOS) | ||
// - \\.\pipe\dotnet-diagnostic-{%d:PID} (Windows) | ||
// | ||
// Refer to documentation for details: | ||
// https://github.com/dotnet/diagnostics/blob/main/documentation/design-docs/ipc-protocol.md#transport | ||
|
@@ -74,6 +79,56 @@ func NewClient(addr string, options ...Option) *Client { | |
return c | ||
} | ||
|
||
func (c *Client) ProcessInfo2() (*ProcessInfo2Response, error) { | ||
conn, err := c.dial(c.addr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer conn.Close() | ||
|
||
if err = writeMessage(conn, CommandSetProcess, ProcessProcessInfo2, nil); err != nil { | ||
return nil, err | ||
} | ||
|
||
var resp ProcessInfo2Response | ||
header, err := readResponseHeader(conn) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if header.CommandSet != CommandSetServer || header.CommandID != 00 { | ||
return nil, fmt.Errorf("unexpected response header: commandSet=%v (expected 0xff) commandID=%v (expected 0x00)", header.CommandSet, header.CommandID) | ||
} | ||
|
||
buf := bytes.NewBuffer(nil) | ||
if _, err := io.CopyN(buf, conn, int64(header.Size-headerSize)); err != nil { | ||
return nil, err | ||
} | ||
|
||
if err := binary.Read(buf, binary.LittleEndian, &resp.ProcessID); err != nil { | ||
return nil, fmt.Errorf("unable to read process ID: %w", err) | ||
} | ||
|
||
if err := binary.Read(buf, binary.LittleEndian, &resp.GUID); err != nil { | ||
return nil, fmt.Errorf("unable to read process ID: %w", err) | ||
} | ||
|
||
// now parse the strings out | ||
p := &nettrace.Parser{Buffer: buf} | ||
p.UTF16NTS() | ||
resp.CommandLine = p.UTF16NTS() | ||
p.UTF16NTS() | ||
resp.OS = p.UTF16NTS() | ||
p.UTF16NTS() | ||
resp.Arch = p.UTF16NTS() | ||
p.UTF16NTS() | ||
resp.AssemblyName = p.UTF16NTS() | ||
p.UTF16NTS() | ||
resp.RuntimeVersion = p.UTF16NTS() | ||
Comment on lines
+103
to
+127
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to check the parser error with nit: It looks like the buffer size is known in advance, probably we should pre-alloc it. Also, for small payloads of known size md := Metadata{p: &Parser{Buffer: blob.Payload}}
md.p.Read(&md.Header.MetaDataID)
md.Header.ProviderName = md.p.UTF16NTS()
md.p.Read(&md.Header.EventID)
md.Header.EventName = md.p.UTF16NTS()
md.p.Read(&md.Header.Keywords)
md.p.Read(&md.Header.Version)
md.p.Read(&md.Header.Level) There's probably a bug in the
|
||
|
||
return &resp, nil | ||
} | ||
|
||
// CollectTracing creates a new EventPipe session stream of NetTrace data. | ||
func (c *Client) CollectTracing(config CollectTracingConfig) (s *Session, err error) { | ||
// Every session has its own IPC connection which cannot be reused for any | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great if we could get the error code when
CommandID
is 0xFFIn
readResponse
we have quite weak check, and a TODO note – I'd fix this: