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