diff options
author | Dave Pacheco <dap@joyent.com> | 2012-03-28 10:26:10 -0700 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2012-04-01 00:14:36 +0000 |
commit | cc15299c32b4fc39c2eb2c08b0265e462f875544 (patch) | |
tree | 2e3c9b283e29e925b8ac4072d67671d164c218de | |
parent | 7bdeed203991d35a56e7448540e3b74387c65d0d (diff) | |
download | node-new-cc15299c32b4fc39c2eb2c08b0265e462f875544.tar.gz |
build: add support for DTrace and postmortem
* fixes #2110
* includes V8 postmortem metadata in Solaris builds
* adds GYP support for DTrace probes and ustack helper
* ustack helper derives constants dynamically from libv8_base.a
* build with DTrace support by default on SunOS
-rw-r--r-- | common.gypi | 3 | ||||
-rwxr-xr-x | configure | 18 | ||||
-rw-r--r-- | node.gyp | 101 | ||||
-rw-r--r-- | src/v8abbr.h | 86 | ||||
-rw-r--r-- | src/v8constants.h | 87 | ||||
-rw-r--r-- | src/v8ustack.d | 1 | ||||
-rwxr-xr-x | tools/genv8constants.py | 82 |
7 files changed, 283 insertions, 95 deletions
diff --git a/common.gypi b/common.gypi index 6e13b6091a..a63fa94b30 100644 --- a/common.gypi +++ b/common.gypi @@ -8,6 +8,7 @@ 'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds 'component%': 'static_library', # NB. these names match with what V8 expects 'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way + 'v8_postmortem_support': 'true', # V8's postmortem metadata }, 'target_defaults': { @@ -42,6 +43,8 @@ }], ['OS=="solaris"', { 'cflags': [ '-fno-omit-frame-pointer' ], + # pull in V8's postmortem metadata + 'ldflags': [ '-Wl,-z,allextract' ] }], ['strict_aliasing!="true"', { 'cflags': [ '-fno-strict-aliasing' ], @@ -108,7 +108,12 @@ parser.add_option("--shared-zlib-libname", parser.add_option("--with-dtrace", action="store_true", dest="with_dtrace", - help="Build with DTrace (experimental)") + help="Build with DTrace (default is true on supported systems)") + +parser.add_option("--without-dtrace", + action="store_true", + dest="without_dtrace", + help="Build without DTrace") # CHECKME does this still work with recent releases of V8? parser.add_option("--gdb", @@ -225,7 +230,6 @@ def gcc_version(): def configure_node(o): # TODO add gdb o['variables']['node_prefix'] = options.prefix if options.prefix else '' - o['variables']['node_use_dtrace'] = b(options.with_dtrace) o['variables']['node_install_npm'] = b(not options.without_npm) o['variables']['node_install_waf'] = b(not options.without_waf) o['variables']['host_arch'] = host_arch() @@ -242,6 +246,16 @@ def configure_node(o): if 'clang' not in CC and gcc_version() < [False, 4, 0, 0]: o['variables']['visibility'] = '' + # By default, enable DTrace on SunOS systems. Don't allow it on other + # systems, since it won't work. (The MacOS build process is different than + # SunOS, and we haven't implemented it.) + if sys.platform.startswith('sunos'): + o['variables']['node_use_dtrace'] = b(not options.without_dtrace); + elif b(options.with_dtrace) == 'true': + raise Exception('DTrace is currently only supported on SunOS systems.') + else: + o['variables']['node_use_dtrace'] = 'false' + def configure_libz(o): o['variables']['node_shared_zlib'] = b(options.shared_zlib) @@ -4,7 +4,7 @@ # Turn off -Werror in V8 # See http://codereview.chromium.org/8159015 'werror': '', - 'node_use_dtrace': 'false', + 'node_use_dtrace%': 'false', 'node_shared_v8%': 'false', 'node_shared_zlib%': 'false', 'node_use_openssl%': 'true', @@ -138,14 +138,26 @@ }], [ 'node_use_dtrace=="true"', { + 'defines': [ 'HAVE_DTRACE=1' ], + 'dependencies': [ 'node_dtrace_header' ], + 'include_dirs': [ '<(SHARED_INTERMEDIATE_DIR)' ], + # + # node_dtrace_provider.cc and node_dtrace_ustack.cc do not actually + # exist. They're here to trick GYP into linking the corresponding + # object files into the final "node" executable. These files are + # generated by "dtrace -G" using custom actions below, and the + # GYP-generated Makefiles will properly build them when needed. + # 'sources': [ 'src/node_dtrace.cc', - 'src/node_dtrace.h', - # why does node_provider.h get generated into src and not - # SHARED_INTERMEDIATE_DIR? - 'src/node_provider.h', + 'src/node_dtrace_provider.cc' ], - }], + 'conditions': [ [ + 'target_arch=="ia32"', { + 'sources': [ 'src/node_dtrace_ustack.cc' ] + } + ] ], + } ], [ 'node_shared_v8=="true"', { 'sources': [ @@ -254,6 +266,83 @@ }, ], }, # end node_js2c + { + 'target_name': 'node_dtrace_header', + 'type': 'none', + 'conditions': [ + [ 'node_use_dtrace=="true"', { + 'actions': [ + { + 'action_name': 'node_dtrace_header', + 'inputs': [ 'src/node_provider.d' ], + 'outputs': [ '<(SHARED_INTERMEDIATE_DIR)/node_provider.h' ], + 'action': [ 'dtrace', '-h', '-xnolibs', '-s', '<@(_inputs)', + '-o', '<@(_outputs)' ] + } + ] + } ] + ] + }, + { + 'target_name': 'node_dtrace_provider', + 'type': 'none', + 'conditions': [ + [ 'node_use_dtrace=="true"', { + 'actions': [ + { + 'action_name': 'node_dtrace_provider_o', + 'inputs': [ + 'src/node_provider.d', + '<(PRODUCT_DIR)/obj.target/node/src/node_dtrace.o' + ], + 'outputs': [ + '<(PRODUCT_DIR)/obj.target/node/src/node_dtrace_provider.o' + ], + 'action': [ 'dtrace', '-G', '-xnolibs', '-s', '<@(_inputs)', + '-o', '<@(_outputs)' ] + } + ] + } ] + ] + }, + { + 'target_name': 'node_dtrace_ustack', + 'type': 'none', + 'conditions': [ + [ 'node_use_dtrace=="true"', { + 'actions': [ + { + 'action_name': 'node_dtrace_ustack_constants', + 'inputs': [ + '<(PRODUCT_DIR)/obj.target/deps/v8/tools/gyp/libv8_base.a' + ], + 'outputs': [ + '<(SHARED_INTERMEDIATE_DIR)/v8constants.h' + ], + 'action': [ + 'tools/genv8constants.py', + '<@(_outputs)', + '<@(_inputs)' + ] + }, + { + 'action_name': 'node_dtrace_ustack', + 'inputs': [ + 'src/v8ustack.d', + '<(SHARED_INTERMEDIATE_DIR)/v8constants.h' + ], + 'outputs': [ + '<(PRODUCT_DIR)/obj.target/node/src/node_dtrace_ustack.o' + ], + 'action': [ + 'dtrace', '-32', '-I<(SHARED_INTERMEDIATE_DIR)', '-Isrc', + '-C', '-G', '-s', 'src/v8ustack.d', '-o', '<@(_outputs)', + ] + } + ] + } ], + ] + } ] # end targets } diff --git a/src/v8abbr.h b/src/v8abbr.h new file mode 100644 index 0000000000..ac4a169395 --- /dev/null +++ b/src/v8abbr.h @@ -0,0 +1,86 @@ +/* + * This header defines short names for V8 constants for use by the ustack + * helper. + */ + +#ifndef V8_ABBR_H +#define V8_ABBR_H + +/* Frame pointer offsets */ +#define V8_OFF_FP_FUNC ((uint32_t)V8DBG_OFF_FP_FUNCTION) +#define V8_OFF_FP_CONTEXT ((uint32_t)V8DBG_OFF_FP_CONTEXT) +#define V8_OFF_FP_MARKER ((uint32_t)V8DBG_OFF_FP_MARKER) + +/* Stack frame types */ +#define V8_FT_ENTRY V8DBG_FRAMETYPE_ENTRYFRAME +#define V8_FT_ENTRYCONSTRUCT V8DBG_FRAMETYPE_ENTRYCONSTRUCTFRAME +#define V8_FT_EXIT V8DBG_FRAMETYPE_EXITFRAME +#define V8_FT_JAVASCRIPT V8DBG_FRAMETYPE_JAVASCRIPTFRAME +#define V8_FT_OPTIMIZED V8DBG_FRAMETYPE_OPTIMIZEDFRAME +#define V8_FT_INTERNAL V8DBG_FRAMETYPE_INTERNALFRAME +#define V8_FT_CONSTRUCT V8DBG_FRAMETYPE_CONSTRUCTFRAME +#define V8_FT_ADAPTOR V8DBG_FRAMETYPE_ARGUMENTSADAPTORFRAME + +/* Identification masks and tags */ +#define V8_SmiTagMask V8DBG_SMITAGMASK +#define V8_SmiTag V8DBG_SMITAG +#define V8_SmiValueShift V8_SmiTagMask + +#define V8_HeapObjectTagMask V8DBG_HEAPOBJECTTAGMASK +#define V8_HeapObjectTag V8DBG_HEAPOBJECTTAG + +#define V8_IsNotStringMask V8DBG_ISNOTSTRINGMASK +#define V8_StringTag V8DBG_STRINGTAG + +#define V8_StringEncodingMask V8DBG_STRINGENCODINGMASK +#define V8_AsciiStringTag V8DBG_ASCIISTRINGTAG + +#define V8_StringRepresentationMask V8DBG_STRINGREPRESENTATIONMASK +#define V8_SeqStringTag V8DBG_SEQSTRINGTAG +#define V8_ConsStringTag V8DBG_CONSSTRINGTAG +#define V8_ExternalStringTag V8DBG_EXTERNALSTRINGTAG + +/* Instance types */ +#define V8_IT_FIXEDARRAY V8DBG_TYPE_FIXEDARRAY__FIXED_ARRAY_TYPE +#define V8_IT_CODE V8DBG_TYPE_CODE__CODE_TYPE + +/* Node-specific offsets */ +#define NODE_OFF_EXTSTR_DATA 0x4 + +/* Heap class->field offsets */ +#define V8_OFF_HEAP(off) ((off) - 1) + +#define V8_OFF_FUNC_SHARED \ + V8_OFF_HEAP(V8DBG_CLASS_JSFUNCTION__SHARED__SHAREDFUNCTIONINFO) +#define V8_OFF_SHARED_NAME \ + V8_OFF_HEAP(V8DBG_CLASS_SHAREDFUNCTIONINFO__NAME__OBJECT) +#define V8_OFF_SHARED_INFERRED \ + V8_OFF_HEAP(V8DBG_CLASS_SHAREDFUNCTIONINFO__INFERRED_NAME__STRING) +#define V8_OFF_SHARED_SCRIPT \ + V8_OFF_HEAP(V8DBG_CLASS_SHAREDFUNCTIONINFO__SCRIPT__OBJECT) +#define V8_OFF_SHARED_FUNTOK \ + V8_OFF_HEAP(V8DBG_CLASS_SHAREDFUNCTIONINFO__FUNCTION_TOKEN_POSITION__SMI) +#define V8_OFF_SCRIPT_NAME \ + V8_OFF_HEAP(V8DBG_CLASS_SCRIPT__NAME__OBJECT) +#define V8_OFF_SCRIPT_LENDS \ + V8_OFF_HEAP(V8DBG_CLASS_SCRIPT__LINE_ENDS__OBJECT) +#define V8_OFF_STR_LENGTH \ + V8_OFF_HEAP(V8DBG_CLASS_STRING__LENGTH__SMI) +#define V8_OFF_STR_CHARS \ + V8_OFF_HEAP(V8DBG_CLASS_SEQASCIISTRING__CHARS__CHAR) +#define V8_OFF_CONSSTR_CAR \ + V8_OFF_HEAP(V8DBG_CLASS_CONSSTRING__FIRST__STRING) +#define V8_OFF_CONSSTR_CDR \ + V8_OFF_HEAP(V8DBG_CLASS_CONSSTRING__SECOND__STRING) +#define V8_OFF_EXTSTR_RSRC \ + V8_OFF_HEAP(V8DBG_CLASS_EXTERNALSTRING__RESOURCE__OBJECT) +#define V8_OFF_FA_SIZE \ + V8_OFF_HEAP(V8DBG_CLASS_FIXEDARRAYBASE__LENGTH__SMI) +#define V8_OFF_FA_DATA \ + V8_OFF_HEAP(V8DBG_CLASS_FIXEDARRAY__DATA__UINTPTR_T) +#define V8_OFF_HEAPOBJ_MAP \ + V8_OFF_HEAP(V8DBG_CLASS_HEAPOBJECT__MAP__MAP) +#define V8_OFF_MAP_ATTRS \ + V8_OFF_HEAP(V8DBG_CLASS_MAP__INSTANCE_ATTRIBUTES__INT) + +#endif /* V8_ABBR_H */ diff --git a/src/v8constants.h b/src/v8constants.h deleted file mode 100644 index 5608493447..0000000000 --- a/src/v8constants.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * The following offsets are derived from the V8 3.6.6.14 source. A future - * version of this helper will automatically generate this file based on the - * debug metadata included in libv8. See v8ustack.d for details on how these - * values are used. - */ - -#ifndef V8_CONSTANTS_H -#define V8_CONSTANTS_H - -#if defined(__i386) - -/* - * Frame pointer offsets - */ -#define V8_OFF_FP_FUNC (-0x8) -#define V8_OFF_FP_CONTEXT (-0x4) -#define V8_OFF_FP_MARKER (-0x8) - -/* - * Heap class->field offsets - */ -#define V8_OFF_HEAP(off) ((off) - 1) - -#define V8_OFF_FUNC_SHARED V8_OFF_HEAP(0x14) -#define V8_OFF_SHARED_NAME V8_OFF_HEAP(0x4) -#define V8_OFF_SHARED_INFERRED V8_OFF_HEAP(0x24) -#define V8_OFF_SHARED_SCRIPT V8_OFF_HEAP(0x1c) -#define V8_OFF_SHARED_FUNTOK V8_OFF_HEAP(0x4c) -#define V8_OFF_SCRIPT_NAME V8_OFF_HEAP(0x8) -#define V8_OFF_SCRIPT_LENDS V8_OFF_HEAP(0x28) -#define V8_OFF_STR_LENGTH V8_OFF_HEAP(0x4) -#define V8_OFF_STR_CHARS V8_OFF_HEAP(0xc) -#define V8_OFF_CONSSTR_CAR V8_OFF_HEAP(0xc) -#define V8_OFF_CONSSTR_CDR V8_OFF_HEAP(0x10) -#define V8_OFF_EXTSTR_RSRC V8_OFF_HEAP(0xc) -#define V8_OFF_FA_SIZE V8_OFF_HEAP(0x4) -#define V8_OFF_FA_DATA V8_OFF_HEAP(0x8) -#define V8_OFF_HEAPOBJ_MAP V8_OFF_HEAP(0x0) -#define V8_OFF_MAP_ATTRS V8_OFF_HEAP(0x8) - -#define NODE_OFF_EXTSTR_DATA 0x4 - -/* - * Stack frame types - */ -#define V8_FT_ENTRY 0x1 -#define V8_FT_ENTRYCONSTRUCT 0x2 -#define V8_FT_EXIT 0x3 -#define V8_FT_JAVASCRIPT 0x4 -#define V8_FT_OPTIMIZED 0x5 -#define V8_FT_INTERNAL 0x6 -#define V8_FT_CONSTRUCT 0x7 -#define V8_FT_ADAPTOR 0x8 - -/* - * Instance types - */ -#define V8_IT_FIXEDARRAY 0x9f -#define V8_IT_CODE 0x81 - -/* - * Identification masks and tags - */ -#define V8_SmiTagMask 0x1 -#define V8_SmiTag 0x0 -#define V8_SmiValueShift V8_SmiTagMask - -#define V8_HeapObjectTagMask 0x3 -#define V8_HeapObjectTag 0x1 - -#define V8_IsNotStringMask 0x80 -#define V8_StringTag 0x0 - -#define V8_StringEncodingMask 0x4 -#define V8_AsciiStringTag 0x4 - -#define V8_StringRepresentationMask 0x3 -#define V8_SeqStringTag 0x0 -#define V8_ConsStringTag 0x1 -#define V8_ExternalStringTag 0x2 - -#else -#error "only i386 is supported for DTrace ustack helper" -#endif - -#endif /* V8_CONSTANTS_H */ diff --git a/src/v8ustack.d b/src/v8ustack.d index 489e55cf36..27e9034492 100644 --- a/src/v8ustack.d +++ b/src/v8ustack.d @@ -11,6 +11,7 @@ */ #include <v8constants.h> +#include <v8abbr.h> /* * V8 represents small integers (SMI) using the upper 31 bits of a 32-bit diff --git a/tools/genv8constants.py b/tools/genv8constants.py new file mode 100755 index 0000000000..5c3defb485 --- /dev/null +++ b/tools/genv8constants.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +# +# genv8constants.py output_file libv8_base.a +# +# Emits v8dbg constants stored in libv8_base.a in a format suitable for the V8 +# ustack helper. +# + +import re +import subprocess +import sys + +if len(sys.argv) != 3: + print "usage: objsym.py outfile libv8_base.a" + sys.exit(2); + +outfile = file(sys.argv[1], 'w'); +pipe = subprocess.Popen([ 'objdump', '-z', '-D', sys.argv[2] ], + stdout=subprocess.PIPE).stdout; +pattern = re.compile('00000000 <(v8dbg_.*)>:'); +numpattern = re.compile('[0-9a-fA-F]{2}'); + +outfile.write(""" +/* + * File automatically generated by genv8constants. Do not edit. + * + * The following offsets are dynamically from libv8_base.a. See src/v8ustack.d + * for details on how these values are used. + */ + +#ifndef V8_CONSTANTS_H +#define V8_CONSTANTS_H + +#if defined(__i386) +"""); + +curr_sym = None; +curr_val = 0; +curr_octet = 0; + +for line in pipe: + if curr_sym != None: + # + # This bit of code has nasty knowledge of the objdump text output + # format, but this is the most obvious robust approach. We could almost + # rely on looking at numbered fields, but some instructions look very + # much like hex numbers (e.g., "adc"), and we don't want to risk picking + # those up by mistake, so we look at character-based columns intead. + # + for i in range (0, 3): + # 6-character margin, 2-characters + 1 space for each field + idx = 6 + i * 3; + octetstr = line[idx:idx+2] + if not numpattern.match(octetstr): + break; + + curr_val += int('0x%s' % octetstr, 16) << (curr_octet * 8); + curr_octet += 1; + + if curr_octet < 4: + continue; + + outfile.write("#define %s 0x%x\n" % (curr_sym.upper(), curr_val)); + curr_sym = None; + curr_val = 0; + curr_octet = 0; + continue; + + match = pattern.match(line) + if match == None: + continue; + + curr_sym = match.group(1); + +outfile.write(""" +#else +#error "only i386 is supported for DTrace ustack helper" +#endif + +#endif /* V8_CONSTANTS_H */ +"""); |