use Node core provider dtrace probe found error
```dtrace script
node*:::http-server-request {
printf("%s of %s from %s\n", args[0]->method,
args[0]->url, args[1]->remoteAddress)
}
```error
dtrace: failed to compile script node_http_latency.d: line 2: operator -> cannot be applied to pointer to type "int"; must be applied to a struct or union pointer
Is this actually a bug in Node core or node-dtrace?
@cjihrig I'm not sure
I use Node core (https://github.com/nodejs/node/blob/master/src/node_provider.d) provider dtrace probe and error occurred
cc @misterdjules - might be relevant to you. The second argument is supposed to be the socket object.
The problem is that the DTrace type translators that allow DTrace to understand the structure of the data at addresses args[0] and args[1] are not loaded by DTrace on your system. Thus, DTrace interprets these addresses as pointers to int.
We can confirm that by looking at the output of the following command:
$ dtrace -v -l -n 'node*:::'
when a node process is running. This will output detailed information about all probes provided by the node DTrace provider, including the type of arguments.
On my OS X setup, I get the following information for the http-server-request probe:
46788 node43929 node _ZN4node26DTRACE_HTTP_SERVER_REQUESTERKN2v820FunctionCallbackInfoINS0_5ValueEEE [node::DTRACE_HTTP_SERVER_REQUEST(v8::FunctionCallbackInfo<v8::Value> const&)] http-server-request
Probe Description Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: Unknown
Argument Attributes
Identifier Names: Evolving
Data Semantics: Evolving
Dependency Class: ISA
Argument Types
args[0]: int *
args[1]: int *
args[2]: char *
args[3]: int
args[4]: char *
args[5]: char *
args[6]: int
Note the following:
args[0]: int *
args[1]: int *
which indicates that the type information that should be provided by the type translators has not been loaded.
That type information is stored in a file at $NODE_INSTALL_PATH/lib/dtrace/node.d, and I think the problem is that DTrace on OSX will only load type translators file from /usr/lib/dtrace. Moving that node.d file to /usr/lib/dtrace doesn't seem to solve the problem, as it seems to have other issues that make it not work on OSX. The first one of them is that it depends on procfs.d, which is provided on SmartOS (and possibly on other Illumos and/or Solaris derivatives), but not provided on OSX. It seems it would make sense to replace that dependency with a dependency on darwin.d, but I wasn't successful in doing that.
I'm still not sure why the translators info cannot be loaded, but it seems this is the root cause of the problem. There's more information at http://dtrace.org/blogs/rm/2011/02/18/fixing-dtrace-libdir-dependency-resolution/ and http://www.mail-archive.com/[email protected]/msg04648.html about the fix for an issue in Illumos that could be related.
The only workaround that I know to work is to perform the type translation in your DTrace script, by rewriting the script in the original comment as following:
#!/usr/sbin/dtrace -s
typedef struct {
int32_t fd;
int32_t port;
uint64_t remote;
uint32_t buffered;
} node_dtrace_connection64_t;
typedef struct {
uint32_t version;
uint32_t pad;
uint64_t url;
uint64_t method;
uint64_t forwardedFor;
} node_dtrace_http_server_request64_v1_t;
node*:::http-server-request {
method = copyinstr(*(uint64_t *)copyin((uintptr_t)
&((node_dtrace_http_server_request64_v1_t *)args[0])->method,
sizeof (uint64_t)));
url = copyinstr(*(uint64_t *)copyin((uintptr_t)
&((node_dtrace_http_server_request64_v1_t *)args[0])->url,
sizeof (uint64_t)));
remoteAddress = copyinstr((uintptr_t)*(uint64_t *)copyin((uintptr_t)
&((node_dtrace_connection64_t *)args[1])->remote, sizeof (int64_t)));
printf("%s of %s from %s\n", method, url, remoteAddress);
}
Note that this DTrace script would not be portable accross 32 and 64 bits binaries, and accross node versions, but it works on my setup with a node v0.10.40 64 bits binary.
@michaelkebe use script it works on my setup with node v4.2.4 64bits
Very Thanks
Digging a bit more into this, it seems that OS X is considered to not support DTrace translators, and thus when DTrace static probes are fired, additional arguments are passed to "flatten" the data that was original passed as structured data.
As a result, on OS X we can rewrite the original DTrace script as following:
#!/usr/sbin/dtrace -s
node*:::http-server-request {
printf("%s of %s from %s\n", copyinstr((uintptr_t)args[4]),
copyinstr((uintptr_t)args[5]), copyinstr((uintptr_t)args[2]))
}
This is much more portable accross architectures and node versions than the previous workaround that I mentioned.
It's still not clear to me why DTrace on OS X doesn't support the translators that ship with node. It might be due to a limitation of the DTrace implementation itself on OS X, or due to the translators shipped with node.
The script that @misterdjules posted in the previous comment is working for me on v4.2.4, v6.10.2, v7.8.0, and master. @feifeiiiiiiiiiii can you post the output of csrutil status?
Hi, @evanlucas @misterdjules posted script work fine, use follow script work file in v4.2.4,v6.10.2, v7.8.0 and master ?
node*:::http-server-request {
printf("%s of %s from %s\n", args[0]->method,
args[0]->url, args[1]->remoteAddress)
}
Should this remain open?
@Trott I think it's fair to close this issue since we've shown how to use probes statically defined within node's core on OSX, even though not being able to leverage DTrace translators makes it a bit less user-friendly.
If that workaround is not good enough, we could open a separate issue to investigate whether it could be possible to make DTrace translators work on OSX.
Thus, closing this issue, please feel free to reopen or comment if you think this is not appropriate.
Most helpful comment
Digging a bit more into this, it seems that OS X is considered to not support DTrace translators, and thus when DTrace static probes are fired, additional arguments are passed to "flatten" the data that was original passed as structured data.
As a result, on OS X we can rewrite the original DTrace script as following:
This is much more portable accross architectures and node versions than the previous workaround that I mentioned.
It's still not clear to me why DTrace on OS X doesn't support the translators that ship with node. It might be due to a limitation of the DTrace implementation itself on OS X, or due to the translators shipped with node.