CPPLINT_EXCLUDE ?=
CPPLINT_EXCLUDE += src/node_dtrace.cc
-CPPLINT_EXCLUDE += src/node_dtrace.cc
+CPPLINT_EXCLUDE += src/node_lttng.cc
CPPLINT_EXCLUDE += src/node_root_certs.h
+CPPLINT_EXCLUDE += src/node_lttng_tp.h
CPPLINT_EXCLUDE += src/node_win32_perfctr_provider.cc
CPPLINT_EXCLUDE += src/queue.h
CPPLINT_EXCLUDE += src/tree.h
dest='with_dtrace',
help='build with DTrace (default is true on sunos)')
+parser.add_option('--with-lttng',
+ action='store_true',
+ dest='with_lttng',
+ help='build with Lttng (Only available to Linux)')
+
parser.add_option('--with-etw',
action='store_true',
dest='with_etw',
else:
o['variables']['node_use_dtrace'] = 'false'
+ # Enable Lttng if --with-lttng was defined. Use logic similar to
+ # ETW for windows. Lttng is only available on the Linux platform.
+ if flavor == 'linux':
+ o['variables']['node_use_lttng'] = b(options.with_lttng)
+ elif options.with_lttng:
+ raise Exception('lttng is only supported on Linux.')
+ else:
+ o['variables']['node_use_lttng'] = 'false'
+
# if we're on illumos based systems wrap the helper library into the
# executable
if flavor == 'solaris':
ClientRequest.prototype._finish = function() {
DTRACE_HTTP_CLIENT_REQUEST(this, this.connection);
+ LTTNG_HTTP_CLIENT_REQUEST(this, this.connection);
COUNTER_HTTP_CLIENT_REQUEST();
OutgoingMessage.prototype._finish.call(this);
};
DTRACE_HTTP_CLIENT_RESPONSE(socket, req);
+ LTTNG_HTTP_CLIENT_RESPONSE(socket, req);
COUNTER_HTTP_CLIENT_RESPONSE();
req.res = res;
res.req = req;
ServerResponse.prototype._finish = function() {
DTRACE_HTTP_SERVER_RESPONSE(this.connection);
+ LTTNG_HTTP_SERVER_RESPONSE(this.connection);
COUNTER_HTTP_SERVER_RESPONSE();
OutgoingMessage.prototype._finish.call(this);
};
res.shouldKeepAlive = shouldKeepAlive;
DTRACE_HTTP_SERVER_REQUEST(req, socket);
+ LTTNG_HTTP_SERVER_REQUEST(req, socket);
COUNTER_HTTP_SERVER_REQUEST();
if (socket._httpMessage) {
stream.Duplex.prototype.end.call(this, data, encoding);
this.writable = false;
DTRACE_NET_STREAM_END(this);
+ LTTNG_NET_STREAM_END(this);
// just in case we're waiting for an EOF.
if (this.readable && !this._readableState.endEmitted)
socket.server = self;
DTRACE_NET_SERVER_CONNECTION(socket);
+ LTTNG_NET_SERVER_CONNECTION(socket);
COUNTER_NET_SERVER_CONNECTION(socket);
self.emit('connection', socket);
}
'variables': {
'v8_use_snapshot%': 'false',
'node_use_dtrace%': 'false',
+ 'node_use_lttng%': 'false',
'node_use_etw%': 'false',
'node_use_perfctr%': 'false',
'node_has_winsdk%': 'false',
}
] ]
} ],
+ [ 'node_use_lttng=="true"', {
+ 'defines': [ 'HAVE_LTTNG=1' ],
+ 'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)' ],
+ 'libraries': [ '-llttng-ust' ],
+ 'sources': [
+ 'src/node_lttng.cc'
+ ],
+ } ],
[ 'node_use_mdb=="true"', {
'dependencies': [ 'node_mdb' ],
'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)' ],
[ 'node_use_dtrace=="false" and node_use_etw=="false"', {
'inputs': [ 'src/notrace_macros.py' ]
}],
+ ['node_use_lttng=="false"', {
+ 'inputs': [ 'src/nolttng_macros.py' ]
+ }],
[ 'node_use_perfctr=="false"', {
'inputs': [ 'src/perfctr_macros.py' ]
}]
#include "node_dtrace.h"
#endif
+#if defined HAVE_LTTNG
+#include "node_lttng.h"
+#endif
+
#include "ares.h"
#include "async-wrap.h"
#include "async-wrap-inl.h"
InitDTrace(env, global);
#endif
+#if defined HAVE_LTTNG
+ InitLTTNG(env, global);
+#endif
+
#if defined HAVE_PERFCTR
InitPerfCounters(env, global);
#endif
--- /dev/null
+#include "util.h"
+
+#ifdef HAVE_LTTNG
+#include "node_lttng.h"
+#include "node_lttng_provider.h"
+#include <string.h>
+#else
+#define NODE_HTTP_SERVER_REQUEST(arg0, arg1)
+#define NODE_HTTP_SERVER_REQUEST_ENABLED() (0)
+#define NODE_HTTP_SERVER_RESPONSE(arg0)
+#define NODE_HTTP_SERVER_RESPONSE_ENABLED() (0)
+#define NODE_HTTP_CLIENT_REQUEST(arg0, arg1)
+#define NODE_HTTP_CLIENT_REQUEST_ENABLED() (0)
+#define NODE_HTTP_CLIENT_RESPONSE(arg0)
+#define NODE_HTTP_CLIENT_RESPONSE_ENABLED() (0)
+#define NODE_NET_SERVER_CONNECTION(arg0)
+#define NODE_NET_SERVER_CONNECTION_ENABLED() (0)
+#define NODE_NET_STREAM_END(arg0)
+#define NODE_NET_STREAM_END_ENABLED() (0)
+#define NODE_GC_START(arg0, arg1, arg2)
+#define NODE_GC_DONE(arg0, arg1, arg2)
+#endif
+
+#include "env.h"
+#include "env-inl.h"
+
+namespace node {
+
+using v8::FunctionCallbackInfo;
+using v8::FunctionTemplate;
+using v8::GCCallbackFlags;
+using v8::GCEpilogueCallback;
+using v8::GCPrologueCallback;
+using v8::GCType;
+using v8::Handle;
+using v8::HandleScope;
+using v8::Isolate;
+using v8::Local;
+using v8::Object;
+using v8::String;
+using v8::Value;
+
+#define SLURP_STRING(obj, member, valp) \
+ if (!(obj)->IsObject()) { \
+ return env->ThrowError( \
+ "expected object for " #obj " to contain string member " #member); \
+ } \
+ node::Utf8Value _##member(env->isolate(), \
+ obj->Get(OneByteString(env->isolate(), #member))); \
+ if ((*(const char **)valp = *_##member) == nullptr) \
+ *(const char **)valp = "<unknown>";
+
+#define SLURP_INT(obj, member, valp) \
+ if (!(obj)->IsObject()) { \
+ return env->ThrowError( \
+ "expected object for " #obj " to contain integer member " #member); \
+ } \
+ *valp = obj->Get(OneByteString(env->isolate(), #member)) \
+ ->ToInteger(env->isolate())->Value();
+
+#define SLURP_OBJECT(obj, member, valp) \
+ if (!(obj)->IsObject()) { \
+ return env->ThrowError( \
+ "expected object for " #obj " to contain object member " #member); \
+ } \
+ *valp = Local<Object>::Cast(obj->Get(OneByteString(env->isolate(), #member)));
+
+#define SLURP_CONNECTION(arg, conn) \
+ if (!(arg)->IsObject()) { \
+ return env->ThrowError( \
+ "expected argument " #arg " to be a connection object"); \
+ } \
+ node_lttng_connection_t conn; \
+ Local<Object> _##conn = Local<Object>::Cast(arg); \
+ Local<Value> _handle = \
+ (_##conn)->Get(FIXED_ONE_BYTE_STRING(env->isolate(), "_handle")); \
+ if (_handle->IsObject()) { \
+ SLURP_INT(_handle.As<Object>(), fd, &conn.fd); \
+ } else { \
+ conn.fd = -1; \
+ } \
+ SLURP_STRING(_##conn, remoteAddress, &conn.remote); \
+ SLURP_INT(_##conn, remotePort, &conn.port); \
+ SLURP_INT(_##conn, bufferSize, &conn.buffered);
+
+#define SLURP_CONNECTION_HTTP_CLIENT(arg, conn) \
+ if (!(arg)->IsObject()) { \
+ return env->ThrowError( \
+ "expected argument " #arg " to be a connection object"); \
+ } \
+ node_lttng_connection_t conn; \
+ Local<Object> _##conn = Local<Object>::Cast(arg); \
+ SLURP_INT(_##conn, fd, &conn.fd); \
+ SLURP_STRING(_##conn, host, &conn.remote); \
+ SLURP_INT(_##conn, port, &conn.port); \
+ SLURP_INT(_##conn, bufferSize, &conn.buffered);
+
+#define SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(arg0, arg1, conn) \
+ if (!(arg0)->IsObject()) { \
+ return env->ThrowError( \
+ "expected argument " #arg0 " to be a connection object"); \
+ } \
+ if (!(arg1)->IsObject()) { \
+ return env->ThrowError( \
+ "expected argument " #arg1 " to be a connection object"); \
+ } \
+ node_lttng_connection_t conn; \
+ Local<Object> _##conn = Local<Object>::Cast(arg0); \
+ SLURP_INT(_##conn, fd, &conn.fd); \
+ SLURP_INT(_##conn, bufferSize, &conn.buffered); \
+ _##conn = Local<Object>::Cast(arg1); \
+ SLURP_STRING(_##conn, host, &conn.remote); \
+ SLURP_INT(_##conn, port, &conn.port);
+
+
+void LTTNG_NET_SERVER_CONNECTION(const FunctionCallbackInfo<Value>& args) {
+ if (!NODE_NET_SERVER_CONNECTION_ENABLED())
+ return;
+ Environment* env = Environment::GetCurrent(args);
+ SLURP_CONNECTION(args[0], conn);
+ NODE_NET_SERVER_CONNECTION(&conn, conn.remote, conn.port, conn.fd);
+}
+
+
+void LTTNG_NET_STREAM_END(const FunctionCallbackInfo<Value>& args) {
+ if (!NODE_NET_STREAM_END_ENABLED())
+ return;
+ Environment* env = Environment::GetCurrent(args);
+ SLURP_CONNECTION(args[0], conn);
+ NODE_NET_STREAM_END(&conn, conn.remote, conn.port, conn.fd);
+}
+
+
+void LTTNG_HTTP_SERVER_REQUEST(const FunctionCallbackInfo<Value>& args) {
+ node_lttng_http_server_request_t req;
+
+ if (!NODE_HTTP_SERVER_REQUEST_ENABLED())
+ return;
+
+ if (!args[0]->IsObject())
+ return;
+
+ Environment* env = Environment::GetCurrent(args);
+ Local<Object> arg0 = args[0].As<Object>();
+ Local<Object> headers;
+
+ memset(&req, 0, sizeof(req));
+ req._un.version = 1;
+ SLURP_STRING(arg0, url, &req.url);
+ SLURP_STRING(arg0, method, &req.method);
+ SLURP_OBJECT(arg0, headers, &headers);
+
+ if (!(headers)->IsObject()) {
+ return env->ThrowError(
+ "expected object for request to contain string member headers");
+ }
+
+ Local<Value> strfwdfor = headers->Get(env->x_forwarded_string());
+ node::Utf8Value fwdfor(env->isolate(), strfwdfor);
+ req.forwarded_for = *fwdfor;
+
+ if (!strfwdfor->IsString() || req.forwarded_for == nullptr)
+ req.forwarded_for = "";
+
+ SLURP_CONNECTION(args[1], conn);
+ NODE_HTTP_SERVER_REQUEST(&req, &conn, conn.remote, conn.port, req.method, \
+ req.url, conn.fd);
+}
+
+
+void LTTNG_HTTP_SERVER_RESPONSE(const FunctionCallbackInfo<Value>& args) {
+ if (!NODE_HTTP_SERVER_RESPONSE_ENABLED())
+ return;
+ Environment* env = Environment::GetCurrent(args);
+ SLURP_CONNECTION(args[0], conn);
+ NODE_HTTP_SERVER_RESPONSE(&conn, conn.remote, conn.port, conn.fd);
+}
+
+
+void LTTNG_HTTP_CLIENT_REQUEST(const FunctionCallbackInfo<Value>& args) {
+ node_lttng_http_client_request_t req;
+ char* header;
+
+ if (!NODE_HTTP_CLIENT_REQUEST_ENABLED())
+ return;
+
+ Environment* env = Environment::GetCurrent(args);
+
+ /*
+ * For the method and URL, we're going to dig them out of the header. This
+ * is not as efficient as it could be, but we would rather not force the
+ * caller here to retain their method and URL until the time at which
+ * LTTNG_HTTP_CLIENT_REQUEST can be called.
+ */
+ Local<Object> arg0 = args[0].As<Object>();
+ SLURP_STRING(arg0, _header, &header);
+
+ req.method = header;
+
+ while (*header != '\0' && *header != ' ')
+ header++;
+
+ if (*header != '\0')
+ *header++ = '\0';
+
+ req.url = header;
+
+ while (*header != '\0' && *header != ' ')
+ header++;
+
+ *header = '\0';
+
+ SLURP_CONNECTION_HTTP_CLIENT(args[1], conn);
+ NODE_HTTP_CLIENT_REQUEST(&req, &conn, conn.remote, conn.port, req.method, \
+ req.url, conn.fd);
+}
+
+
+void LTTNG_HTTP_CLIENT_RESPONSE(const FunctionCallbackInfo<Value>& args) {
+ if (!NODE_HTTP_CLIENT_RESPONSE_ENABLED())
+ return;
+ Environment* env = Environment::GetCurrent(args);
+ SLURP_CONNECTION_HTTP_CLIENT_RESPONSE(args[0], args[1], conn);
+ NODE_HTTP_CLIENT_RESPONSE(&conn, conn.remote, conn.port, conn.fd);
+}
+
+
+void lttng_gc_start(Isolate* isolate, GCType type, GCCallbackFlags flags) {
+ NODE_GC_START(type, flags, isolate);
+}
+
+
+void lttng_gc_done(Isolate* isolate, GCType type, GCCallbackFlags flags) {
+ NODE_GC_DONE(type, flags, isolate);
+}
+
+void InitLTTNG(Environment* env, Handle<Object> target) {
+ HandleScope scope(env->isolate());
+
+ static struct {
+ const char *name;
+ void (*func)(const FunctionCallbackInfo<Value>&);
+ } tab[] = {
+#define NODE_PROBE(name) #name, name
+ { NODE_PROBE(LTTNG_NET_SERVER_CONNECTION) },
+ { NODE_PROBE(LTTNG_NET_STREAM_END) },
+ { NODE_PROBE(LTTNG_HTTP_SERVER_REQUEST) },
+ { NODE_PROBE(LTTNG_HTTP_SERVER_RESPONSE) },
+ { NODE_PROBE(LTTNG_HTTP_CLIENT_REQUEST) },
+ { NODE_PROBE(LTTNG_HTTP_CLIENT_RESPONSE) }
+#undef NODE_PROBE
+ };
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(tab); i++) {
+ Local<String> key = OneByteString(env->isolate(), tab[i].name);
+ Local<Value> val = env->NewFunctionTemplate(tab[i].func)->GetFunction();
+ target->Set(key, val);
+ }
+
+#if defined HAVE_LTTNG
+ env->isolate()->AddGCPrologueCallback(lttng_gc_start);
+ env->isolate()->AddGCEpilogueCallback(lttng_gc_done);
+#endif
+}
+
+} // namespace node
--- /dev/null
+#ifndef SRC_NODE_LTTNG_H_
+#define SRC_NODE_LTTNG_H_
+
+#include "node.h"
+#include "v8.h"
+#include "env.h"
+
+extern "C" {
+typedef struct {
+ int32_t fd;
+ int32_t port;
+ const char* remote;
+ int32_t buffered;
+} node_lttng_connection_t;
+
+typedef struct {
+ const char* url;
+ const char* method;
+} node_lttng_http_client_request_t;
+
+typedef struct {
+ union {
+ uint32_t version;
+ uintptr_t unused; /* for compat. with old 64-bit struct */
+ } _un;
+ const char* url;
+ const char* method;
+ const char* forwarded_for;
+ const char* _pad[8];
+} node_lttng_http_server_request_t;
+
+} // extern "C"
+
+namespace node {
+
+void InitLTTNG(Environment* env, v8::Handle<v8::Object> target);
+
+} // namespace node
+
+#endif // SRC_NODE_LTTNG_H_
--- /dev/null
+#ifndef SRC_NODE_LTTNG_PROVIDER_H_
+#define SRC_NODE_LTTNG_PROVIDER_H_
+
+#define TRACEPOINT_CREATE_PROBES
+#define TRACEPOINT_DEFINE
+#include "node_lttng_tp.h"
+
+namespace node {
+
+void NODE_HTTP_SERVER_REQUEST(node_lttng_http_server_request_t* req,
+ node_lttng_connection_t* conn,
+ const char *remote, int port,
+ const char *method, const char *url,
+ int fd) {
+ tracepoint(node, http_server_request, req->url, req->method, \
+ req->forwarded_for);
+}
+
+void NODE_HTTP_SERVER_RESPONSE(node_lttng_connection_t* conn,
+ const char *remote, int port, int fd) {
+ tracepoint(node, http_server_response, port, conn->remote, fd);
+}
+
+void NODE_HTTP_CLIENT_REQUEST(node_lttng_http_client_request_t* req,
+ node_lttng_connection_t* conn,
+ const char *remote, int port,
+ const char *method, const char *url,
+ int fd) {
+ tracepoint(node, http_client_request, req->url, req->method);
+}
+
+void NODE_HTTP_CLIENT_RESPONSE(node_lttng_connection_t* conn,
+ const char *remote, int port, int fd) {
+ tracepoint(node, http_client_response, port, conn->remote, fd);
+}
+
+void NODE_NET_SERVER_CONNECTION(node_lttng_connection_t* conn,
+ const char *remote, int port, int fd) {
+ tracepoint(node, net_server_connection, conn->remote, port, fd, \
+ conn->buffered);
+}
+
+void NODE_NET_STREAM_END(node_lttng_connection_t* conn,
+ const char *remote, int port, int fd) {
+ tracepoint(node, net_stream_end, conn->remote, port, fd);
+}
+
+void NODE_GC_START(v8::GCType type,
+ v8::GCCallbackFlags flags,
+ v8::Isolate* isolate) {
+ const char* typeStr = "";
+ const char* flagsStr = "";
+ if (type == v8::GCType::kGCTypeScavenge) {
+ typeStr = "kGCTypeScavenge";
+ } else if (type == v8::GCType::kGCTypeMarkSweepCompact) {
+ typeStr = "kGCTypeMarkSweepCompact";
+ } else if (type == v8::GCType::kGCTypeAll) {
+ typeStr = "kGCTypeAll";
+ }
+ if (flags == v8::GCCallbackFlags::kNoGCCallbackFlags) {
+ flagsStr = "kNoGCCallbackFlags";
+ } else if (flags == v8::GCCallbackFlags::kGCCallbackFlagCompacted) {
+ flagsStr = "kGCCallbackFlagCompacted";
+ }
+
+ tracepoint(node, gc_start, typeStr, flagsStr);
+}
+
+
+void NODE_GC_DONE(v8::GCType type,
+ v8::GCCallbackFlags flags,
+ v8::Isolate* isolate) {
+ const char* typeStr = "";
+ const char* flagsStr = "";
+ if (type == v8::GCType::kGCTypeScavenge) {
+ typeStr = "kGCTypeScavenge";
+ } else if (type == v8::GCType::kGCTypeMarkSweepCompact) {
+ typeStr = "kGCTypeMarkSweepCompact";
+ } else if (type == v8::GCType::kGCTypeAll) {
+ typeStr = "kGCTypeAll";
+ }
+ if (flags == v8::GCCallbackFlags::kNoGCCallbackFlags) {
+ flagsStr = "kNoGCCallbackFlags";
+ } else if (flags == v8::GCCallbackFlags::kGCCallbackFlagCompacted) {
+ flagsStr = "kGCCallbackFlagCompacted";
+ }
+
+ tracepoint(node, gc_done, typeStr, flagsStr);
+}
+
+bool NODE_HTTP_SERVER_REQUEST_ENABLED() { return true; }
+bool NODE_HTTP_SERVER_RESPONSE_ENABLED() { return true; }
+bool NODE_HTTP_CLIENT_REQUEST_ENABLED() { return true; }
+bool NODE_HTTP_CLIENT_RESPONSE_ENABLED() { return true; }
+bool NODE_NET_SERVER_CONNECTION_ENABLED() { return true; }
+bool NODE_NET_STREAM_END_ENABLED() { return true; }
+
+} // namespace node
+
+#endif // SRC_NODE_LTTNG_PROVIDER_H_
--- /dev/null
+#undef TRACEPOINT_PROVIDER
+#define TRACEPOINT_PROVIDER node
+
+#undef TRACEPOINT_INCLUDE
+#define TRACEPOINT_INCLUDE "./node_lttng_tp.h"
+
+#if !defined(__NODE_LTTNG_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
+#define __NODE_LTTNG_TP_H
+
+#include <lttng/tracepoint.h>
+
+TRACEPOINT_EVENT(
+ node,
+ http_server_request,
+ TP_ARGS(
+ const char*, url,
+ const char*, method,
+ const char*, forwardedFor
+ ),
+ TP_FIELDS(
+ ctf_string(url, url)
+ ctf_string(method, method)
+ ctf_string(forwardedFor, forwardedFor)
+ )
+)
+
+TRACEPOINT_EVENT(
+ node,
+ http_server_response,
+ TP_ARGS(
+ int, port,
+ const char*, remote,
+ int, fd
+ ),
+ TP_FIELDS(
+ ctf_integer(int, port, port)
+ ctf_string(remote, remote)
+ ctf_integer(int, fd, fd)
+ )
+)
+
+TRACEPOINT_EVENT(
+ node,
+ http_client_request,
+ TP_ARGS(
+ const char*, url,
+ const char*, method
+ ),
+ TP_FIELDS(
+ ctf_string(url, url)
+ ctf_string(method, method)
+ )
+)
+
+TRACEPOINT_EVENT(
+ node,
+ http_client_response,
+ TP_ARGS(
+ int, port,
+ const char*, remote,
+ int, fd
+ ),
+ TP_FIELDS(
+ ctf_integer(int, port, port)
+ ctf_string(remote, remote)
+ ctf_integer(int, fd, fd)
+ )
+)
+
+TRACEPOINT_EVENT(
+ node,
+ net_server_connection,
+ TP_ARGS(
+ const char*, remote,
+ int, port,
+ int, fd,
+ int, buffered
+ ),
+ TP_FIELDS(
+ ctf_string(remote, remote)
+ ctf_integer(int, port, port)
+ ctf_integer(int, fd, fd)
+ ctf_integer(int, buffered, buffered)
+ )
+)
+
+TRACEPOINT_EVENT(
+ node,
+ net_stream_end,
+ TP_ARGS(
+ const char*, remote,
+ int, port,
+ int, fd
+ ),
+ TP_FIELDS(
+ ctf_string(remote, remote)
+ ctf_integer(int, port, port)
+ ctf_integer(int, fd, fd)
+ )
+)
+
+TRACEPOINT_EVENT(
+ node,
+ gc_start,
+ TP_ARGS(
+ const char*, gctype,
+ const char*, gcflags
+ ),
+ TP_FIELDS(
+ ctf_string(gctype, gctype)
+ ctf_string(gcflags, gcflags)
+ )
+)
+
+TRACEPOINT_EVENT(
+ node,
+ gc_done,
+ TP_ARGS(
+ const char*, gctype,
+ const char*, gcflags
+ ),
+ TP_FIELDS(
+ ctf_string(gctype, gctype)
+ ctf_string(gcflags, gcflags)
+ )
+)
+
+#endif /* __NODE_LTTNG_TP_H */
+
+#include <lttng/tracepoint-event.h>
--- /dev/null
+# This file is used by tools/js2c.py to preprocess out the LTTNG symbols in
+# builds that don't support LTTNG. This is not used in builds that support
+# LTTNG.
+macro LTTNG_HTTP_CLIENT_REQUEST(x) = ;
+macro LTTNG_HTTP_CLIENT_RESPONSE(x) = ;
+macro LTTNG_HTTP_SERVER_REQUEST(x) = ;
+macro LTTNG_HTTP_SERVER_RESPONSE(x) = ;
+macro LTTNG_NET_SERVER_CONNECTION(x) = ;
+macro LTTNG_NET_STREAM_END(x) = ;
knownGlobals.push(COUNTER_HTTP_CLIENT_RESPONSE);
}
+if (global.LTTNG_HTTP_SERVER_RESPONSE) {
+ knownGlobals.push(LTTNG_HTTP_SERVER_RESPONSE);
+ knownGlobals.push(LTTNG_HTTP_SERVER_REQUEST);
+ knownGlobals.push(LTTNG_HTTP_CLIENT_RESPONSE);
+ knownGlobals.push(LTTNG_HTTP_CLIENT_REQUEST);
+ knownGlobals.push(LTTNG_NET_STREAM_END);
+ knownGlobals.push(LTTNG_NET_SERVER_CONNECTION);
+}
+
if (global.ArrayBuffer) {
knownGlobals.push(ArrayBuffer);
knownGlobals.push(Int8Array);
var spawn = require('child_process').spawn;
var child = spawn(process.execPath, [__filename, 'child'], {
- env: { NODE_DEBUG: environ }
+ // Lttng requires the HOME env variable or it prints to stderr,
+ // This is not really ideal, as it breaks this test, so the HOME
+ // env variable is passed to the child to make the test pass.
+ // this is fixed in the next version of lttng (2.7+), so we can
+ // remove it at sometime in the future.
+ env: { NODE_DEBUG: environ, HOME: process.env.HOME }
});
expectErr = expectErr.split('%PID%').join(child.pid);