|
@ -19,14 +19,23 @@ |
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
|
#include "node_dtrace.h" |
|
|
|
|
|
#include <string.h> |
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_DTRACE |
|
|
#ifdef HAVE_DTRACE |
|
|
|
|
|
#include "node_dtrace.h" |
|
|
|
|
|
#include <string.h> |
|
|
#include "node_provider.h" |
|
|
#include "node_provider.h" |
|
|
#elif HAVE_ETW |
|
|
#elif HAVE_ETW |
|
|
|
|
|
#include "node_dtrace.h" |
|
|
|
|
|
#include <string.h> |
|
|
#include "node_win32_etw_provider.h" |
|
|
#include "node_win32_etw_provider.h" |
|
|
#include "node_win32_etw_provider-inl.h" |
|
|
#include "node_win32_etw_provider-inl.h" |
|
|
|
|
|
#elif HAVE_SYSTEMTAP |
|
|
|
|
|
#include <string.h> |
|
|
|
|
|
#include <node.h> |
|
|
|
|
|
#include <v8.h> |
|
|
|
|
|
#include <sys/sdt.h> |
|
|
|
|
|
#include "node_systemtap.h" |
|
|
|
|
|
#include "node_dtrace.h" |
|
|
#else |
|
|
#else |
|
|
#define NODE_HTTP_SERVER_REQUEST(arg0, arg1) |
|
|
#define NODE_HTTP_SERVER_REQUEST(arg0, arg1) |
|
|
#define NODE_HTTP_SERVER_REQUEST_ENABLED() (0) |
|
|
#define NODE_HTTP_SERVER_REQUEST_ENABLED() (0) |
|
@ -118,67 +127,86 @@ using namespace v8; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Handle<Value> DTRACE_NET_SERVER_CONNECTION(const Arguments& args) { |
|
|
Handle<Value> DTRACE_NET_SERVER_CONNECTION(const Arguments& args) { |
|
|
|
|
|
#ifndef HAVE_SYSTEMTAP |
|
|
if (!NODE_NET_SERVER_CONNECTION_ENABLED()) |
|
|
if (!NODE_NET_SERVER_CONNECTION_ENABLED()) |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
SLURP_CONNECTION(args[0], conn); |
|
|
SLURP_CONNECTION(args[0], conn); |
|
|
|
|
|
#ifdef HAVE_SYSTEMTAP |
|
|
|
|
|
NODE_NET_SERVER_CONNECTION(conn.fd, conn.remote, conn.port, \ |
|
|
|
|
|
conn.buffered); |
|
|
|
|
|
#else |
|
|
NODE_NET_SERVER_CONNECTION(&conn); |
|
|
NODE_NET_SERVER_CONNECTION(&conn); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Handle<Value> DTRACE_NET_STREAM_END(const Arguments& args) { |
|
|
Handle<Value> DTRACE_NET_STREAM_END(const Arguments& args) { |
|
|
|
|
|
#ifndef HAVE_SYSTEMTAP |
|
|
if (!NODE_NET_STREAM_END_ENABLED()) |
|
|
if (!NODE_NET_STREAM_END_ENABLED()) |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
SLURP_CONNECTION(args[0], conn); |
|
|
SLURP_CONNECTION(args[0], conn); |
|
|
|
|
|
#ifdef HAVE_SYSTEMTAP |
|
|
|
|
|
NODE_NET_STREAM_END(conn.fd, conn.remote, conn.port, conn.buffered); |
|
|
|
|
|
#else |
|
|
NODE_NET_STREAM_END(&conn); |
|
|
NODE_NET_STREAM_END(&conn); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Handle<Value> DTRACE_NET_SOCKET_READ(const Arguments& args) { |
|
|
Handle<Value> DTRACE_NET_SOCKET_READ(const Arguments& args) { |
|
|
|
|
|
#ifndef HAVE_SYSTEMTAP |
|
|
if (!NODE_NET_SOCKET_READ_ENABLED()) |
|
|
if (!NODE_NET_SOCKET_READ_ENABLED()) |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
int nbytes; |
|
|
|
|
|
|
|
|
|
|
|
SLURP_CONNECTION(args[0], conn); |
|
|
SLURP_CONNECTION(args[0], conn); |
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_SYSTEMTAP |
|
|
|
|
|
NODE_NET_SOCKET_READ(conn.fd, conn.remote, conn.port, conn.buffered); |
|
|
|
|
|
#else |
|
|
if (!args[1]->IsNumber()) { |
|
|
if (!args[1]->IsNumber()) { |
|
|
return (ThrowException(Exception::Error(String::New("expected " |
|
|
return (ThrowException(Exception::Error(String::New("expected " |
|
|
"argument 1 to be number of bytes")))); |
|
|
"argument 1 to be number of bytes")))); |
|
|
} |
|
|
} |
|
|
|
|
|
int nbytes = args[1]->Int32Value(); |
|
|
nbytes = args[1]->Int32Value(); |
|
|
|
|
|
|
|
|
|
|
|
NODE_NET_SOCKET_READ(&conn, nbytes); |
|
|
NODE_NET_SOCKET_READ(&conn, nbytes); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Handle<Value> DTRACE_NET_SOCKET_WRITE(const Arguments& args) { |
|
|
Handle<Value> DTRACE_NET_SOCKET_WRITE(const Arguments& args) { |
|
|
|
|
|
#ifndef HAVE_SYSTEMTAP |
|
|
if (!NODE_NET_SOCKET_WRITE_ENABLED()) |
|
|
if (!NODE_NET_SOCKET_WRITE_ENABLED()) |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
int nbytes; |
|
|
|
|
|
|
|
|
|
|
|
SLURP_CONNECTION(args[0], conn); |
|
|
SLURP_CONNECTION(args[0], conn); |
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_SYSTEMTAP |
|
|
|
|
|
NODE_NET_SOCKET_WRITE(conn.fd, conn.remote, conn.port, conn.buffered); |
|
|
|
|
|
#else |
|
|
if (!args[1]->IsNumber()) { |
|
|
if (!args[1]->IsNumber()) { |
|
|
return (ThrowException(Exception::Error(String::New("expected " |
|
|
return (ThrowException(Exception::Error(String::New("expected " |
|
|
"argument 1 to be number of bytes")))); |
|
|
"argument 1 to be number of bytes")))); |
|
|
} |
|
|
} |
|
|
|
|
|
int nbytes = args[1]->Int32Value(); |
|
|
nbytes = args[1]->Int32Value(); |
|
|
|
|
|
|
|
|
|
|
|
NODE_NET_SOCKET_WRITE(&conn, nbytes); |
|
|
NODE_NET_SOCKET_WRITE(&conn, nbytes); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
} |
|
|
} |
|
@ -186,8 +214,10 @@ Handle<Value> DTRACE_NET_SOCKET_WRITE(const Arguments& args) { |
|
|
Handle<Value> DTRACE_HTTP_SERVER_REQUEST(const Arguments& args) { |
|
|
Handle<Value> DTRACE_HTTP_SERVER_REQUEST(const Arguments& args) { |
|
|
node_dtrace_http_server_request_t req; |
|
|
node_dtrace_http_server_request_t req; |
|
|
|
|
|
|
|
|
|
|
|
#ifndef HAVE_SYSTEMTAP |
|
|
if (!NODE_HTTP_SERVER_REQUEST_ENABLED()) |
|
|
if (!NODE_HTTP_SERVER_REQUEST_ENABLED()) |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
|
|
|
|
|
@ -213,18 +243,29 @@ Handle<Value> DTRACE_HTTP_SERVER_REQUEST(const Arguments& args) { |
|
|
|
|
|
|
|
|
SLURP_CONNECTION(args[1], conn); |
|
|
SLURP_CONNECTION(args[1], conn); |
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_SYSTEMTAP |
|
|
|
|
|
NODE_HTTP_SERVER_REQUEST(&req, conn.fd, conn.remote, conn.port, \ |
|
|
|
|
|
conn.buffered); |
|
|
|
|
|
#else |
|
|
NODE_HTTP_SERVER_REQUEST(&req, &conn); |
|
|
NODE_HTTP_SERVER_REQUEST(&req, &conn); |
|
|
|
|
|
#endif |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Handle<Value> DTRACE_HTTP_SERVER_RESPONSE(const Arguments& args) { |
|
|
Handle<Value> DTRACE_HTTP_SERVER_RESPONSE(const Arguments& args) { |
|
|
|
|
|
#ifndef HAVE_SYSTEMTAP |
|
|
if (!NODE_HTTP_SERVER_RESPONSE_ENABLED()) |
|
|
if (!NODE_HTTP_SERVER_RESPONSE_ENABLED()) |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
SLURP_CONNECTION(args[0], conn); |
|
|
SLURP_CONNECTION(args[0], conn); |
|
|
|
|
|
#ifdef HAVE_SYSTEMTAP |
|
|
|
|
|
NODE_HTTP_SERVER_RESPONSE(conn.fd, conn.remote, conn.port, conn.buffered); |
|
|
|
|
|
#else |
|
|
NODE_HTTP_SERVER_RESPONSE(&conn); |
|
|
NODE_HTTP_SERVER_RESPONSE(&conn); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
} |
|
|
} |
|
@ -233,8 +274,10 @@ Handle<Value> DTRACE_HTTP_CLIENT_REQUEST(const Arguments& args) { |
|
|
node_dtrace_http_client_request_t req; |
|
|
node_dtrace_http_client_request_t req; |
|
|
char *header; |
|
|
char *header; |
|
|
|
|
|
|
|
|
|
|
|
#ifndef HAVE_SYSTEMTAP |
|
|
if (!NODE_HTTP_CLIENT_REQUEST_ENABLED()) |
|
|
if (!NODE_HTTP_CLIENT_REQUEST_ENABLED()) |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
|
|
|
|
|
@ -263,26 +306,40 @@ Handle<Value> DTRACE_HTTP_CLIENT_REQUEST(const Arguments& args) { |
|
|
*header = '\0'; |
|
|
*header = '\0'; |
|
|
|
|
|
|
|
|
SLURP_CONNECTION_HTTP_CLIENT(args[1], conn); |
|
|
SLURP_CONNECTION_HTTP_CLIENT(args[1], conn); |
|
|
|
|
|
#ifdef HAVE_SYSTEMTAP |
|
|
|
|
|
NODE_HTTP_CLIENT_REQUEST(&req, conn.fd, conn.remote, conn.port, \ |
|
|
|
|
|
conn.buffered); |
|
|
|
|
|
#else |
|
|
NODE_HTTP_CLIENT_REQUEST(&req, &conn); |
|
|
NODE_HTTP_CLIENT_REQUEST(&req, &conn); |
|
|
|
|
|
#endif |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Handle<Value> DTRACE_HTTP_CLIENT_RESPONSE(const Arguments& args) { |
|
|
Handle<Value> DTRACE_HTTP_CLIENT_RESPONSE(const Arguments& args) { |
|
|
|
|
|
#ifndef HAVE_SYSTEMTAP |
|
|
if (!NODE_HTTP_CLIENT_RESPONSE_ENABLED()) |
|
|
if (!NODE_HTTP_CLIENT_RESPONSE_ENABLED()) |
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
|
|
|
#endif |
|
|
HandleScope scope; |
|
|
HandleScope scope; |
|
|
|
|
|
|
|
|
SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(args[0], args[1], conn); |
|
|
SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(args[0], args[1], conn); |
|
|
|
|
|
#ifdef HAVE_SYSTEMTAP |
|
|
|
|
|
NODE_HTTP_CLIENT_RESPONSE(conn.fd, conn.remote, conn.port, conn.buffered); |
|
|
|
|
|
#else |
|
|
NODE_HTTP_CLIENT_RESPONSE(&conn); |
|
|
NODE_HTTP_CLIENT_RESPONSE(&conn); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
return Undefined(); |
|
|
return Undefined(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#define NODE_PROBE(name) #name, name |
|
|
#define NODE_PROBE(name) #name, name, Persistent<FunctionTemplate>() |
|
|
|
|
|
|
|
|
static int dtrace_gc_start(GCType type, GCCallbackFlags flags) { |
|
|
static int dtrace_gc_start(GCType type, GCCallbackFlags flags) { |
|
|
|
|
|
#ifdef HAVE_SYSTEMTAP |
|
|
|
|
|
NODE_GC_START(); |
|
|
|
|
|
#else |
|
|
NODE_GC_START(type, flags); |
|
|
NODE_GC_START(type, flags); |
|
|
|
|
|
#endif |
|
|
/*
|
|
|
/*
|
|
|
* We avoid the tail-call elimination of the USDT probe (which screws up |
|
|
* We avoid the tail-call elimination of the USDT probe (which screws up |
|
|
* args) by forcing a return of 0. |
|
|
* args) by forcing a return of 0. |
|
@ -291,7 +348,11 @@ static int dtrace_gc_start(GCType type, GCCallbackFlags flags) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static int dtrace_gc_done(GCType type, GCCallbackFlags flags) { |
|
|
static int dtrace_gc_done(GCType type, GCCallbackFlags flags) { |
|
|
|
|
|
#ifdef HAVE_SYSTEMTAP |
|
|
|
|
|
NODE_GC_DONE(); |
|
|
|
|
|
#else |
|
|
NODE_GC_DONE(type, flags); |
|
|
NODE_GC_DONE(type, flags); |
|
|
|
|
|
#endif |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -308,11 +369,10 @@ void InitDTrace(Handle<Object> target) { |
|
|
{ NODE_PROBE(DTRACE_HTTP_SERVER_REQUEST) }, |
|
|
{ NODE_PROBE(DTRACE_HTTP_SERVER_REQUEST) }, |
|
|
{ NODE_PROBE(DTRACE_HTTP_SERVER_RESPONSE) }, |
|
|
{ NODE_PROBE(DTRACE_HTTP_SERVER_RESPONSE) }, |
|
|
{ NODE_PROBE(DTRACE_HTTP_CLIENT_REQUEST) }, |
|
|
{ NODE_PROBE(DTRACE_HTTP_CLIENT_REQUEST) }, |
|
|
{ NODE_PROBE(DTRACE_HTTP_CLIENT_RESPONSE) }, |
|
|
{ NODE_PROBE(DTRACE_HTTP_CLIENT_RESPONSE) } |
|
|
{ NULL } |
|
|
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
for (int i = 0; tab[i].name != NULL; i++) { |
|
|
for (unsigned int i = 0; i < ARRAY_SIZE(tab); i++) { |
|
|
tab[i].templ = Persistent<FunctionTemplate>::New( |
|
|
tab[i].templ = Persistent<FunctionTemplate>::New( |
|
|
FunctionTemplate::New(tab[i].func)); |
|
|
FunctionTemplate::New(tab[i].func)); |
|
|
target->Set(String::NewSymbol(tab[i].name), tab[i].templ->GetFunction()); |
|
|
target->Set(String::NewSymbol(tab[i].name), tab[i].templ->GetFunction()); |
|
@ -322,7 +382,7 @@ void InitDTrace(Handle<Object> target) { |
|
|
init_etw(); |
|
|
init_etw(); |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#if defined HAVE_DTRACE || defined HAVE_ETW |
|
|
#if defined HAVE_DTRACE || defined HAVE_ETW || defined HAVE_SYSTEMTAP |
|
|
v8::V8::AddGCPrologueCallback((GCPrologueCallback)dtrace_gc_start); |
|
|
v8::V8::AddGCPrologueCallback((GCPrologueCallback)dtrace_gc_start); |
|
|
v8::V8::AddGCEpilogueCallback((GCEpilogueCallback)dtrace_gc_done); |
|
|
v8::V8::AddGCEpilogueCallback((GCEpilogueCallback)dtrace_gc_done); |
|
|
#endif |
|
|
#endif |
|
|