11cb0ef41Sopenharmony_ci# v8windbg
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciV8windbg is a WinDbg extension for the V8 engine. It adjusts the behavior of the
41cb0ef41Sopenharmony_ciLocals pane and corresponding `dx` commands to display useful data when
51cb0ef41Sopenharmony_ciinspecting V8 object types. It is intended to be as robust as possible in dumps
61cb0ef41Sopenharmony_ciwith limited memory, and should work equally well in live sessions, crash dumps,
71cb0ef41Sopenharmony_ciand time travel debugging.
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci## Building
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciRun `autoninja v8windbg` in your output directory.
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci## Using
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciIn WinDbgX, run `.load path\to\your\output\dir\v8windbg.dll` to load the
161cb0ef41Sopenharmony_ciextension. To inspect V8 objects, use the Locals window or the `dx` command as
171cb0ef41Sopenharmony_ciusual.
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci**Important notes:**
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci- The version of v8windbg must exactly match the version and build configuration
221cb0ef41Sopenharmony_ci  of the process you're debugging. (To find the version number of a module in a
231cb0ef41Sopenharmony_ci  crash dump, enter `lm` and click the module name, or run `lmDvm modulename`.)
241cb0ef41Sopenharmony_ci- V8windbg relies on detailed symbols (symbol_level = 2).
251cb0ef41Sopenharmony_ci- Ensure also that WinDbg can load the symbols (.pdb file) for the module
261cb0ef41Sopenharmony_ci  containing V8.
271cb0ef41Sopenharmony_ci- Cross-architecture debugging is possible in some cases:
281cb0ef41Sopenharmony_ci  - To debug an x86 process on x64, load the x86 build of v8windbg.
291cb0ef41Sopenharmony_ci  - To debug an ARM64 process on x64, load the ARM64 simulator build of v8windbg
301cb0ef41Sopenharmony_ci    (built with target_cpu="x64" and v8_target_cpu="arm64").
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ciAs well as improving the Locals pane behavior, v8windbg also provides a few
331cb0ef41Sopenharmony_cifunctions that can be called from within `dx` commands:
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci- `@$v8object()` returns information about the fields of a tagged V8 value,
361cb0ef41Sopenharmony_ci  passed in as a plain number like `dx @$v8object(0x34f49880471)`. This invokes
371cb0ef41Sopenharmony_ci  the same logic that is used for the locals pane. You may also pass a type hint
381cb0ef41Sopenharmony_ci  as an optional second parameter if you find that v8windbg is not inferring the
391cb0ef41Sopenharmony_ci  correct type (which can happen when the memory for the object's Map wasn't
401cb0ef41Sopenharmony_ci  collected in a crash dump). The type hint is a fully-qualified C++ class name,
411cb0ef41Sopenharmony_ci  like `dx @$v8object(0x34f49880471, "v8::internal::JSArray")`.
421cb0ef41Sopenharmony_ci- `@$curisolate()` gets the Isolate pointer for the current thread, if the
431cb0ef41Sopenharmony_ci  current thread has a JavaScript Isolate associated.
441cb0ef41Sopenharmony_ci- `@$jsstack()` returns a list of the JS stack frames, including information 
451cb0ef41Sopenharmony_ciabout script and function.
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci*Tip:*: to see what objects are present in a chunk of heap memory, you can cast
481cb0ef41Sopenharmony_ciit to an array of `TaggedValue`, like this:
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci`dx (v8::internal::TaggedValue(*)[64])0x34f49880450`
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci## Architecture
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ciV8windbg uses the [DataModel] as much as possible as opposed to the older
551cb0ef41Sopenharmony_ci[DbgEng] APIs. It uses the [WRL COM] APIs due to limitations in Clang's support
561cb0ef41Sopenharmony_cifor [C++/WinRT COM].
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ciWhere possible, v8windbg uses the cross-platform v8_debug_helper library to
591cb0ef41Sopenharmony_ciavoid depending on V8 internals.
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ciThe source in `./base` is a generic starting point for implementing a WinDbg
621cb0ef41Sopenharmony_ciextension. The V8-specific implementation under `./src` then implements the two
631cb0ef41Sopenharmony_cifunctions declared in `dbgext.h` to create and destroy the extension instance.
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci`./src` file index:
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci- `cur-isolate.{cc,h}` implements the `IModelMethod` for `@$curisolate()`.
681cb0ef41Sopenharmony_ci- `js-stack.{cc,h}` implements the `IModelMethod` for `@$jsstack()`. Its
691cb0ef41Sopenharmony_ci  result is a custom object that supports iteration and indexing. 
701cb0ef41Sopenharmony_ci- `local-variables.{cc,h}` implements the `IModelPropertyAccessor` that provides
711cb0ef41Sopenharmony_ci  content to show in the Locals pane for stack frames corresponding to builtins
721cb0ef41Sopenharmony_ci  or runtime-generated code.
731cb0ef41Sopenharmony_ci- `object-inspection.{cc,h}` contains various classes that allow the debugger to
741cb0ef41Sopenharmony_ci  show fields within V8 objects.
751cb0ef41Sopenharmony_ci- `v8-debug-helper-interop.{cc,h}` makes requests to the V8 postmortem debugging
761cb0ef41Sopenharmony_ci  API, and converts the results into simple C++ structs.
771cb0ef41Sopenharmony_ci- `v8windbg-extension.{cc,h}` is responsible for initializing the extension and
781cb0ef41Sopenharmony_ci  cleaning up when the extension is unloaded.
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ciWhen the extension is initialized (`Extension::Initialize()`):
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci- It registers a "parent model" for all known V8 object types, such as
831cb0ef41Sopenharmony_ci  `v8::internal::HeapObject` and `v8::internal::Symbol`. Any time WinDbg needs
841cb0ef41Sopenharmony_ci  to represent a value with one of these types, it creates an `IModelObject`
851cb0ef41Sopenharmony_ci  representing the value and attaches the parent model. This particular parent
861cb0ef41Sopenharmony_ci  model supports `IStringDisplayableConcept` and `IDynamicKeyProviderConcept`,
871cb0ef41Sopenharmony_ci  meaning the debugger will call a custom method every time it wants to get a
881cb0ef41Sopenharmony_ci  description string or a list of fields for any of these objects.
891cb0ef41Sopenharmony_ci- It registers a different parent model, with a single property getter named
901cb0ef41Sopenharmony_ci  "Value", for handle types such as `v8::internal::Handle<*>`. The "Value"
911cb0ef41Sopenharmony_ci  getter returns the correctly-typed tagged pointer contained by the handle.
921cb0ef41Sopenharmony_ci- It overrides the getter functions for "LocalVariables" and "Parameters" on the
931cb0ef41Sopenharmony_ci  parent model for stack frames. When the user selects a stack frame, WinDbg
941cb0ef41Sopenharmony_ci  calls these getter functions to determine what it should show in the Locals
951cb0ef41Sopenharmony_ci  pane.
961cb0ef41Sopenharmony_ci- It registers the function aliases such as `@$curisolate()`.
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ciThe `./test` directory contains a test function that exercises v8windbg. It does
991cb0ef41Sopenharmony_cinot require WinDbg, but uses DbgEng.dll and DbgModel.dll from the Windows SDK
1001cb0ef41Sopenharmony_ci(these are slightly older versions of the same modules used by WinDbg). The test
1011cb0ef41Sopenharmony_cifunction launches a separate d8 process, attaches to that process as a debugger,
1021cb0ef41Sopenharmony_cilets d8 run until it hits a breakpoint, and then checks the output of a few `dx`
1031cb0ef41Sopenharmony_cicommands.
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci## Debugging the extension
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ciTo debug the extension, launch a WinDbgx instance to debug with an active
1081cb0ef41Sopenharmony_citarget, e.g.
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci`windbgx \src\github\v8\out\x64.debug\d8.exe -e "console.log('hello');"`
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_cior
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci`windbgx \src\github\v8\out\x64.debug\d8.exe c:\temp\test.js`
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ciThe WinDbgx process itself does not host the extensions, but uses a helper
1171cb0ef41Sopenharmony_ciprocess. Attach another instance of WinDbgx to the `enghost.exe` helper process,
1181cb0ef41Sopenharmony_cie.g.
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci`windbgx -pn enghost.exe`
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ciSet a breakpoint in this second session for when the extension initializes, e.g.
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci`bm v8windbg!DebugExtensionInitialize`
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci..and/or whenever a function of interest is invoked, e.g.
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci - `bp v8windbg!CurrIsolateAlias::Call` for the invocation of `@$curisolate()`
1291cb0ef41Sopenharmony_ci - `bp v8windbg!GetHeapObject` for the interpretation of V8 objects.
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_ciLoad the extension in the target debugger (the first WinDbg session), which
1321cb0ef41Sopenharmony_cishould trigger the breakpoint.
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci`.load "C:\\src\\github\\v8windbg\\x64\\v8windbg.dll"`
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ciNote: For D8, the below is a good breakpoint to set just before any script is
1371cb0ef41Sopenharmony_cirun:
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci`bp d8_exe!v8::Shell::ExecuteString`
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci..or the below for once the V8 engine is entered (for component builds):
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci`bp v8!v8::Script::Run`
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ciThen trigger the extension code of interest via something like `dx source` or
1461cb0ef41Sopenharmony_ci`dx @$curisolate()`.
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci[DataModel]: https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/data-model-cpp-overview
1491cb0ef41Sopenharmony_ci[DbgEng]: https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/writing-dbgeng-extension-code
1501cb0ef41Sopenharmony_ci[C++/WinRT COM]: https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/consume-com
1511cb0ef41Sopenharmony_ci[WRL COM]: https://docs.microsoft.com/en-us/cpp/cppcx/wrl/windows-runtime-cpp-template-library-wrl?view=vs-2019
152