Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Pacheco <dap@joyent.com>2012-02-03 05:02:09 +0400
committerBen Noordhuis <info@bnoordhuis.nl>2012-02-03 18:07:32 +0400
commit9fb088e3ab71ed88a9cbf1f7e6c3bbe30e8d2f1a (patch)
treefe45859dab1d843ef647c8e3f5a851baecc248fc /src/node.d
parent74a2528bd71ced1061aee2ae7f171d7c446a7bfd (diff)
dtrace: add missing translator
Add missing translator for node_dtrace_http_*_request_t types. Fixes #2667.
Diffstat (limited to 'src/node.d')
-rw-r--r--src/node.d222
1 files changed, 189 insertions, 33 deletions
diff --git a/src/node.d b/src/node.d
index c666127fffc..fae2378437e 100644
--- a/src/node.d
+++ b/src/node.d
@@ -64,26 +64,63 @@ translator node_connection_t <node_dtrace_connection_t *nc> {
&((node_dtrace_connection64_t *)nc)->buffered, sizeof (int32_t));
};
+/*
+ * 32-bit and 64-bit structures received from node for HTTP client request
+ * probe.
+ */
+typedef struct {
+ uint32_t url;
+ uint32_t method;
+} node_dtrace_http_client_request_t;
+
+typedef struct {
+ uint64_t url;
+ uint64_t method;
+} node_dtrace_http_client_request64_t;
+
+/*
+ * The following structures are never used directly, but must exist to bind the
+ * types specified in the provider to the translators defined here.
+ * Ultimately, they always get cast to a more specific type inside the
+ * translator. To add to the confusion, the DTrace compiler does not allow
+ * declaring two translators with the same destination type if the source types
+ * are structures with the same size (because libctf says they're compatible,
+ * so dtrace considers them equivalent). Since we must define translators from
+ * node_dtrace_http_client_request_t (above), node_dtrace_http_request_t, and
+ * node_dtrace_http_server_request_t (both below), each of these three structs
+ * must be declared with a different size.
+ */
typedef struct {
uint32_t version;
+ uint64_t dummy1;
} node_dtrace_http_request_t;
typedef struct {
+ uint32_t version;
+ uint64_t dummy2;
+ uint64_t dummy3;
+} node_dtrace_http_server_request_t;
+
+/*
+ * Actual 32-bit and 64-bit, v0 and v1 structures received from node for the
+ * HTTP server request probe.
+ */
+typedef struct {
uint32_t url;
uint32_t method;
-} node_dtrace_http_request_v0_t;
+} node_dtrace_http_server_request_v0_t;
typedef struct {
uint32_t version;
uint32_t url;
uint32_t method;
uint32_t forwardedFor;
-} node_dtrace_http_request_v1_t;
+} node_dtrace_http_server_request_v1_t;
typedef struct {
uint64_t url;
uint64_t method;
-} node_dtrace_http_request64_v0_t;
+} node_dtrace_http_server_request64_v0_t;
typedef struct {
uint32_t version;
@@ -91,8 +128,13 @@ typedef struct {
uint64_t url;
uint64_t method;
uint64_t forwardedFor;
-} node_dtrace_http_request64_v1_t;
+} node_dtrace_http_server_request64_v1_t;
+/*
+ * In the end, both client and server request probes from both old and new
+ * binaries translate their arguments to node_http_request_t, which is what the
+ * user's D script ultimately sees.
+ */
typedef struct {
string url;
string method;
@@ -100,60 +142,174 @@ typedef struct {
} node_http_request_t;
/*
- * This translator is even filthier than usual owing to our attempts to
- * maintain backwards compatibility. Previous versions of node used an
- * http_request struct that had fields for "url" and "method". The current
- * version also provides a "forwardedFor" field. To distinguish the binary
- * representations of these structs, the new version also prepends a "version"
- * member (where the old one has a "url" pointer). So each field that we're
- * translating below first switches on the value of this "version" field: if
- * it's larger than 4096, we know we must be looking at the "url" pointer of
- * the older structure version. Otherwise, we must be looking at the new
- * version. Besides this, we have the usual switch based on the userland
- * process data model. This would all be simpler with macros, but those aren't
- * available in delivered D library files since that would make DTrace
- * dependent on cpp, which isn't always available.
+ * The following translators are particularly filthy for reasons of backwards
+ * compatibility. Stable versions of node prior to 0.6 used a single
+ * http_request struct with fields for "url" and "method" for both client and
+ * server probes. 0.6 added a "forwardedFor" field intended for the server
+ * probe only, and the http_request struct passed by the application was split
+ * first into client_http_request and server_http_request and the latter was
+ * again split for v0 (the old struct) and v1.
+ *
+ * To distinguish the binary representations of the two versions of these
+ * structs, the new version prepends a "version" member (where the old one has
+ * a "url" pointer). Each field that we're translating below first switches on
+ * the value of this "version" field: if it's larger than 4096, we know we must
+ * be looking at the "url" pointer of the older structure version. Otherwise,
+ * we must be looking at the new version. Besides this, we have the usual
+ * switch based on the userland process data model. This would all be simpler
+ * with macros, but those aren't available in D library files since we cannot
+ * rely on cpp being present at runtime.
+ *
+ * In retrospect, the versioning bit might have been unnecessary since the type
+ * of the object passed in should allow DTrace to select which translator to
+ * use. However, DTrace does sometimes use translators whose source types
+ * don't quite match, and since we know this versioning logic works, we just
+ * leave it alone. Each of the translators below is functionally identical
+ * (except that the client -> client translator doesn't bother translating
+ * forwardedFor) and should actually work with any version of any of the client
+ * or server structs transmitted by the application up to this point.
*/
-translator node_http_request_t <node_dtrace_http_request_t *nd> {
- url = (*(uint32_t *)copyin((uintptr_t)&nd->version, sizeof (uint32_t))) >= 4096 ?
+
+/*
+ * Translate from node_dtrace_http_server_request_t (received from node 0.6 and
+ * later versions) to node_http_request_t.
+ */
+translator node_http_request_t <node_dtrace_http_server_request_t *nd> {
+ url = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
+ sizeof (uint32_t))) >= 4096 ?
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request_v0_t *)nd)->url,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request64_v0_t *)nd)->url,
+ sizeof (uint64_t)))) :
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request_v1_t *)nd)->url,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request64_v1_t *)nd)->url,
+ sizeof (uint64_t))));
+
+ method = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
+ sizeof (uint32_t))) >= 4096 ?
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request_v0_t *)nd)->method,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request64_v0_t *)nd)->method,
+ sizeof (uint64_t)))) :
(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
copyinstr(*(uint32_t *)copyin((uintptr_t)
- &((node_dtrace_http_request_v0_t *)nd)->url,
+ &((node_dtrace_http_server_request_v1_t *)nd)->method,
sizeof (uint32_t))) :
copyinstr(*(uint64_t *)copyin((uintptr_t)
- &((node_dtrace_http_request64_v0_t *)nd)->url,
+ &((node_dtrace_http_server_request64_v1_t *)nd)->method,
+ sizeof (uint64_t))));
+
+ forwardedFor = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
+ sizeof (uint32_t))) >= 4096 ? "" :
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request_v1_t *)nd)->forwardedFor,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request64_v1_t *)nd)->
+ forwardedFor, sizeof (uint64_t))));
+};
+
+/*
+ * Translate from node_dtrace_http_client_request_t (received from node 0.6 and
+ * later versions) to node_http_request_t.
+ */
+translator node_http_request_t <node_dtrace_http_client_request_t *nd> {
+ url = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
+ sizeof (uint32_t))) >= 4096 ?
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request_v0_t *)nd)->url,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request64_v0_t *)nd)->url,
sizeof (uint64_t)))) :
(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
copyinstr(*(uint32_t *)copyin((uintptr_t)
- &((node_dtrace_http_request_v1_t *)nd)->url,
+ &((node_dtrace_http_server_request_v1_t *)nd)->url,
sizeof (uint32_t))) :
copyinstr(*(uint64_t *)copyin((uintptr_t)
- &((node_dtrace_http_request64_v1_t *)nd)->url,
+ &((node_dtrace_http_server_request64_v1_t *)nd)->url,
sizeof (uint64_t))));
- method = (*(uint32_t *)copyin((uintptr_t)&nd->version, sizeof (uint32_t))) >= 4096 ?
+ method = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
+ sizeof (uint32_t))) >= 4096 ?
(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
copyinstr(*(uint32_t *)copyin((uintptr_t)
- &((node_dtrace_http_request_v0_t *)nd)->method,
+ &((node_dtrace_http_server_request_v0_t *)nd)->method,
sizeof (uint32_t))) :
copyinstr(*(uint64_t *)copyin((uintptr_t)
- &((node_dtrace_http_request64_v0_t *)nd)->method,
+ &((node_dtrace_http_server_request64_v0_t *)nd)->method,
sizeof (uint64_t)))) :
(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
copyinstr(*(uint32_t *)copyin((uintptr_t)
- &((node_dtrace_http_request_v1_t *)nd)->method,
+ &((node_dtrace_http_server_request_v1_t *)nd)->method,
sizeof (uint32_t))) :
copyinstr(*(uint64_t *)copyin((uintptr_t)
- &((node_dtrace_http_request64_v1_t *)nd)->method,
+ &((node_dtrace_http_server_request64_v1_t *)nd)->method,
sizeof (uint64_t))));
-
- forwardedFor = (*(uint32_t *)
- copyin((uintptr_t)&nd->version, sizeof (uint32_t))) >= 4096 ? "" :
+
+ forwardedFor = "";
+};
+
+/*
+ * Translate from node_dtrace_http_request_t (received from versions of node
+ * prior to 0.6) to node_http_request_t. This is used for both the server and
+ * client probes since these versions of node didn't distinguish between the
+ * types used in these probes.
+ */
+translator node_http_request_t <node_dtrace_http_request_t *nd> {
+ url = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
+ sizeof (uint32_t))) >= 4096 ?
(curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
copyinstr(*(uint32_t *)copyin((uintptr_t)
- &((node_dtrace_http_request_v1_t *)nd)->forwardedFor,
+ &((node_dtrace_http_server_request_v0_t *)nd)->url,
sizeof (uint32_t))) :
copyinstr(*(uint64_t *)copyin((uintptr_t)
- &((node_dtrace_http_request64_v1_t *)nd)->forwardedFor,
+ &((node_dtrace_http_server_request64_v0_t *)nd)->url,
+ sizeof (uint64_t)))) :
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request_v1_t *)nd)->url,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request64_v1_t *)nd)->url,
+ sizeof (uint64_t))));
+
+ method = (*(uint32_t *)copyin((uintptr_t)(uint32_t *)nd,
+ sizeof (uint32_t))) >= 4096 ?
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request_v0_t *)nd)->method,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request64_v0_t *)nd)->method,
+ sizeof (uint64_t)))) :
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request_v1_t *)nd)->method,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request64_v1_t *)nd)->method,
sizeof (uint64_t))));
+
+ forwardedFor = (*(uint32_t *) copyin((uintptr_t)(uint32_t *)nd,
+ sizeof (uint32_t))) >= 4096 ? "" :
+ (curpsinfo->pr_dmodel == PR_MODEL_ILP32 ?
+ copyinstr(*(uint32_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request_v1_t *)nd)->forwardedFor,
+ sizeof (uint32_t))) :
+ copyinstr(*(uint64_t *)copyin((uintptr_t)
+ &((node_dtrace_http_server_request64_v1_t *)nd)->
+ forwardedFor, sizeof (uint64_t))));
};