Repository: nodejs/node
Pull request: tools: add v8windbg target

[v8windbg](https://github.com/nodejs/node/tree/main/deps/v8/tools/v8windbg) is an extension to WinDbg for debugging coredumps and live debugs on Windows. The version of `v8windbg` must exactly match the version and build configuration of the process being debugged.

This patch adds a configure option to build `v8windbg` with the V8 version and build configuration that `node.exe` is built with.

Changed files:
filename: configure.py
patch: @@ -628,6 +628,12 @@
     default=None,
     help=argparse.SUPPRESS)  # Unsupported, undocumented.
 
+parser.add_argument('--enable-v8windbg',
+    action='store_true',
+    dest='enable_v8windbg',
+    default=None,
+    help=argparse.SUPPRESS)  # Undocumented.
+
 parser.add_argument('--enable-trace-maps',
     action='store_true',
     dest='trace_maps',
@@ -1798,10 +1804,13 @@ def configure_v8(o, configs):
   o['variables']['node_use_bundled_v8'] = b(not options.without_bundled_v8)
   o['variables']['force_dynamic_crt'] = 1 if options.shared else 0
   o['variables']['node_enable_d8'] = b(options.enable_d8)
+  o['variables']['node_enable_v8windbg'] = b(options.enable_v8windbg)
   if options.enable_d8:
     o['variables']['test_isolation_mode'] = 'noop'  # Needed by d8.gyp.
   if options.without_bundled_v8 and options.enable_d8:
     raise Exception('--enable-d8 is incompatible with --without-bundled-v8.')
+  if options.without_bundled_v8 and options.enable_v8windbg:
+    raise Exception('--enable-v8windbg is incompatible with --without-bundled-v8.')
   if options.static_zoslib_gyp:
     o['variables']['static_zoslib_gyp'] = options.static_zoslib_gyp
   if flavor != 'linux' and options.v8_enable_hugepage:

filename: node.gypi
patch: @@ -85,6 +85,9 @@
     [ 'node_enable_d8=="true"', {
       'dependencies': [ 'tools/v8_gypfiles/d8.gyp:d8' ],
     }],
+    [ 'node_enable_v8windbg=="true"', {
+      'dependencies': [ 'tools/v8_gypfiles/v8windbg.gyp:build_v8windbg' ],
+    }],
     [ 'node_use_bundled_v8=="true"', {
       'dependencies': [
         'tools/v8_gypfiles/v8.gyp:v8_snapshot',

filename: tools/v8_gypfiles/v8windbg.gyp
patch: @@ -0,0 +1,168 @@
+{
+  'variables': {
+    'V8_ROOT': '../../deps/v8',
+    'v8_code': 1,
+  },
+  'includes': ['toolchain.gypi', 'features.gypi'],
+  'targets': [
+    {
+      # Intermediate target to build v8windbg.dll.
+      # This prevents the dependent settings like node.gypi to link the v8windbg.dll
+      # to the dependent. v8windbg.dll is only supposed to be loaded by WinDbg at debug time.
+      'target_name': 'build_v8windbg',
+      'type': 'none',
+      'hard_dependency': 1,
+      'dependencies': [
+        'v8windbg',
+      ],
+    },  # build_v8windbg
+    {
+      'target_name': 'v8windbg',
+      'type': 'shared_library',
+      'include_dirs': [
+        '<(V8_ROOT)',
+        '<(V8_ROOT)/include',
+      ],
+      'dependencies': [
+        'v8_debug_helper',
+        'v8.gyp:v8_libbase',
+      ],
+      'sources': [
+        '<!@pymod_do_main(GN-scraper "<(V8_ROOT)/tools/v8windbg/BUILD.gn"  "v8windbg_base.*?sources = ")',
+        '<!@pymod_do_main(GN-scraper "<(V8_ROOT)/tools/v8windbg/BUILD.gn"  "v8_shared_library..v8windbg.*?sources = ")',
+      ],
+      "link_settings": {
+        "libraries": [
+          "-lDbgEng.lib",
+          "-lDbgModel.lib",
+          "-lRuntimeObject.lib",
+          "-lcomsuppwd.lib",
+        ],
+      },
+    },  # v8windbg
+    {
+      'target_name': 'v8_debug_helper',
+      'type': 'static_library',
+      'include_dirs': [
+        '<(V8_ROOT)',
+        '<(V8_ROOT)/include',
+      ],
+      'dependencies': [
+        'gen_heap_constants',
+
+        'abseil.gyp:abseil',
+        'v8.gyp:generate_bytecode_builtins_list',
+        'v8.gyp:run_torque',
+        'v8.gyp:v8_maybe_icu',
+        'v8.gyp:fp16',
+        'v8.gyp:v8_libbase',
+        'v8.gyp:v8_snapshot',
+      ],
+      'sources': [
+        '<!@pymod_do_main(GN-scraper "<(V8_ROOT)/tools/debug_helper/BUILD.gn"  "\"v8_debug_helper_internal\".*?sources = ")',
+        "<(SHARED_INTERMEDIATE_DIR)/torque-generated/class-debug-readers.cc",
+        "<(SHARED_INTERMEDIATE_DIR)/torque-generated/class-debug-readers.h",
+        "<(SHARED_INTERMEDIATE_DIR)/torque-generated/debug-macros.cc",
+        "<(SHARED_INTERMEDIATE_DIR)/torque-generated/debug-macros.h",
+        "<(SHARED_INTERMEDIATE_DIR)/torque-generated/instance-types.h",
+      ],
+      # Enable RTTI //build/config/compiler:rtti
+      'cflags_cc': [ '-frtti' ],
+      'cflags_cc!': [ '-fno-rtti' ],
+      'xcode_settings': {
+        'GCC_ENABLE_CPP_RTTI': 'YES',  # -frtti
+      },
+      'msvs_settings': {
+        'VCCLCompilerTool': {
+          'RuntimeTypeInfo': 'true',
+        },
+      },
+      'configurations': {
+        'Release': { # Override target_defaults.Release in common.gypi
+          'msvs_settings': {
+            'VCCLCompilerTool': {
+              'RuntimeTypeInfo': 'true',
+            },
+          },
+        },
+      },
+    },  # v8_debug_helper
+    {
+      'target_name': 'gen_heap_constants',
+      'type': 'none',
+      'hard_dependency': 1,
+      'dependencies': [
+        'run_mkgrokdump',
+      ],
+      'direct_dependent_settings': {
+        'sources': [
+          '<(SHARED_INTERMEDIATE_DIR)/heap-constants-gen.cc',
+        ],
+      },
+      'actions': [
+        {
+          'action_name': 'run_gen_heap_constants',
+          'inputs': [
+            '<(V8_ROOT)/tools/debug_helper/gen-heap-constants.py',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/heap-constants-gen.cc',
+          ],
+          'action': [
+            '<(python)',
+            '<(V8_ROOT)/tools/debug_helper/gen-heap-constants.py',
+            '<(SHARED_INTERMEDIATE_DIR)',
+            '<@(_outputs)',
+          ]
+        }
+      ]
+    },  # gen_heap_constants
+    {
+      'target_name': 'run_mkgrokdump',
+      'type': 'none',
+      'hard_dependency': 1,
+      'dependencies': [
+        'mkgrokdump',
+      ],
+      'actions': [
+        {
+          'action_name': 'run_gen_heap_constants',
+          'inputs': [
+            '<(V8_ROOT)/tools/run.py',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/v8heapconst.py',
+          ],
+          'action': [
+            '<(python)',
+            '<(V8_ROOT)/tools/run.py',
+            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mkgrokdump<(EXECUTABLE_SUFFIX)',
+            '--outfile',
+            '<@(_outputs)',
+          ]
+        }
+      ]
+    },  # run_mkgrokdump
+    {
+      'target_name': 'mkgrokdump',
+      'type': 'executable',
+      'include_dirs': [
+        '<(V8_ROOT)',
+        '<(V8_ROOT)/include',
+      ],
+      'dependencies': [
+        'abseil.gyp:abseil',
+        'v8.gyp:v8_snapshot',
+        'v8.gyp:v8_libbase',
+        'v8.gyp:v8_libplatform',
+        'v8.gyp:v8_maybe_icu',
+        'v8.gyp:fp16',
+        'v8.gyp:generate_bytecode_builtins_list',
+        'v8.gyp:run_torque',
+      ],
+      'sources': [
+        '<!@pymod_do_main(GN-scraper "<(V8_ROOT)/test/mkgrokdump/BUILD.gn"  "mkgrokdump.*?sources = ")',
+      ]
+    },  # mkgrokdump
+  ],
+}

filename: vcbuild.bat
patch: @@ -72,6 +72,7 @@ set doc=
 set extra_msbuild_args=
 set compile_commands=
 set cfg=
+set v8windbg=
 set exit_code=0
 
 :next-arg
@@ -95,6 +96,7 @@ if /i "%1"=="sign"          set sign=1&goto arg-ok
 if /i "%1"=="nosnapshot"    set nosnapshot=1&goto arg-ok
 if /i "%1"=="nonpm"         set nonpm=1&goto arg-ok
 if /i "%1"=="ltcg"          set ltcg=1&goto arg-ok
+if /i "%1"=="v8windbg"      set v8windbg=1&goto arg-ok
 if /i "%1"=="licensertf"    set licensertf=1&goto arg-ok
 if /i "%1"=="test"          set test_args=%test_args% %common_test_suites%&set lint_cpp=1&set lint_js=1&set lint_md=1&goto arg-ok
 if /i "%1"=="test-ci-native" set test_args=%test_args% %test_ci_args% -p tap --logfile test.tap %CI_NATIVE_SUITES% %CI_DOC%&set build_addons=1&set build_js_native_api_tests=1&set build_node_api_tests=1&set cctest_args=%cctest_args% --gtest_output=xml:cctest.junit.xml&goto arg-ok
@@ -210,6 +212,7 @@ if defined DEBUG_HELPER     set configure_flags=%configure_flags% --verbose
 if defined ccache_path      set configure_flags=%configure_flags% --use-ccache-win
 if defined compile_commands set configure_flags=%configure_flags% -C
 if defined cfg              set configure_flags=%configure_flags% --control-flow-guard
+if defined v8windbg         set configure_flags=%configure_flags% --enable-v8windbg
 
 if "%target_arch%"=="x86" (
   echo "32-bit Windows builds are not supported anymore."