v8dbg_* symbols not available when NodeJS is statically linked with V8 #4274

wants to merge 1 commit into


None yet

2 participants


When NodeJS is statically linked with libv8_base.a, which is the default, I've found that the v8dbg_* debug symbols generated by deps/v8/tools/gen-postmortem-metadata.py are not included in the node binaries. This makes debugging with GDB or writing DTrace or SystemTap probes more difficult than needed (see tools/genv8constants.py).

After some hunting around, I found that while debug-support.cc is being generated and compiled, the debug-support.o object file is never linked into the node binaries. This is because the linker decides that nothing in the node binary actually uses anything defined in debug-support.o, and skips the object file entirely.

I've found a surprisingly trivial fix: instead of a C++ file, create a header file instead, then #include it somewhere which is certainly going to get linked into node.

Any comments and suggestions are very welcome.

Tested with gdb and SystemTap

$ gdb out/Debug/node
(gdb) p v8dbg_SmiTagMask
$1 = 1
# stap -e 'probe process.function("main") { printf("%s: %s(%d)\n", pp(), execname(), pid()); printf("v8dbg_SmiTagMask = %d\n", @var("v8dbg_SmiTagMask@v8.cc")) }' -c out/Debug/node
process("/home/miki/vcs/git/node/out/Debug/node").function("main@../src/node_main.cc:64"): node(10908)
v8dbg_SmiTagMask = 1
@ackalker ackalker Fix v8dbg_* symbols not being linked in when statically linking v8
When linking static libraries, linkers usually skip objects which
they consider not to be used by anything else in the final binary.

Fix this by generating a header file instead of a cc file, and
including that in a module which is certainly going to be linked.

I would like to invite @bnoordhuis to have a look at this issue, since it affects v8's d8 and shell as well.


Another alternative could be to use something like this: put all the debug variables in a self-initializing struct.



#ifndef _V8VARS_DEF

typedef struct v8vars {
#define V8VAR(type, name, value)    type name;
#define _V8VARS_DEF


} v8vars_t;
v8vars_t v8dbg = {

#define V8VAR(type, name, value)    value,


V8VAR(int, initialized, 0)
V8VAR(int, var1, 42)
V8VAR(char, var2, 'a')



void v8dbg_init() {
    v8dbg.initialized = 1;


#undef V8VAR
#include "debug-support.h"




#include <stdio.h>
#include <stdlib.h>

#include "debug-support.h"

int main(int argc, char *argv[]) {
    printf("Hello, world!\n");
    printf("The answer is: %d\n", v8dbg.var1);

Though it may look hideous, it actually has a purpose: the preprocessor has to parse the header file twice, the v8dbg struct will be fully initialized at the end of the last pass.

This solution has several advantages:

  • Although v8dbg is a struct, the generator script needs to loop over the list of variables only once.
  • calling an initialize function which modifies a member of the struct will force the linker to include it in the final binary.
  • the v8dbg_initialize() function makes a perfect target for an stap process.function probe to pick up the variables.

Again, any suggestions are very welcome.

@ackalker ackalker closed this Nov 18, 2012
Node.js Foundation member

@ackalker Is there a reason you closed this PR?

I've found a surprisingly trivial fix: instead of a C++ file, create a header file instead, then #include it somewhere which is certainly going to get linked into node.

The default symbol visibility is 'hidden' so I don't think that's going to work. Compiling with -fdata-sections -Wl,--gc-sections or -flto will almost certainly strip the symbols. You'd have to tag the generated symbols with __attribute__((visibility("default"))) to stop that from happening.

That said, we don't usually take V8 patches. I may make an exception in this case because it's obviously useful but I'd rather you send it upstream first.


Thanks for your time :-)
The reason I closed the PR was that I thought that my first solution was too messy. I now have a tested, working patch.. I will open a new PR with pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment