af76dd6e7e
Please take a look at tools/v8windbg/README.md for an overview of what v8windbg can do and how it's structured. This platform-specific debugging plugin makes use of the data provided by the V8 postmortem debugging API in tools/debug_helper. Note: This code began as https://github.com/billti/v8dbg and then moved into the Edge repository, where I added features gradually and got code reviews for individual changes. Now, taken in its entirety, it's an obnoxiously large CL. I'm open to breaking it up into a few chunks if that would be preferable. Bug: v8:9376 Change-Id: I3e503de00bb1aea870ae83e9bd99e4e2eab9ef98 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2031700 Reviewed-by: Michael Stanton <mvstanton@chromium.org> Reviewed-by: Tamer Tas <tmrts@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Commit-Queue: Seth Brenith <seth.brenith@microsoft.com> Cr-Commit-Position: refs/heads/master@{#66319}
95 lines
3.8 KiB
C++
95 lines
3.8 KiB
C++
// Copyright 2020 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "tools/v8windbg/src/cur-isolate.h"
|
|
|
|
HRESULT GetIsolateKey(WRL::ComPtr<IDebugHostContext>& sp_ctx,
|
|
int* isolate_key) {
|
|
auto sp_v8_module = Extension::Current()->GetV8Module(sp_ctx);
|
|
if (sp_v8_module == nullptr) return E_FAIL;
|
|
|
|
WRL::ComPtr<IDebugHostSymbol> sp_isolate_sym;
|
|
RETURN_IF_FAIL(sp_v8_module->FindSymbolByName(kIsolateKey, &sp_isolate_sym));
|
|
SymbolKind kind;
|
|
RETURN_IF_FAIL(sp_isolate_sym->GetSymbolKind(&kind));
|
|
if (kind != SymbolData) return E_FAIL;
|
|
WRL::ComPtr<IDebugHostData> sp_isolate_key_data;
|
|
RETURN_IF_FAIL(sp_isolate_sym.As(&sp_isolate_key_data));
|
|
Location loc;
|
|
RETURN_IF_FAIL(sp_isolate_key_data->GetLocation(&loc));
|
|
ULONG64 bytes_read;
|
|
RETURN_IF_FAIL(sp_debug_host_memory->ReadBytes(
|
|
sp_ctx.Get(), loc, isolate_key, sizeof(isolate_key), &bytes_read));
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT GetCurrentIsolate(WRL::ComPtr<IModelObject>& sp_result) {
|
|
sp_result = nullptr;
|
|
|
|
// Get the current context
|
|
WRL::ComPtr<IDebugHostContext> sp_host_context;
|
|
RETURN_IF_FAIL(sp_debug_host->GetCurrentContext(&sp_host_context));
|
|
|
|
WRL::ComPtr<IModelObject> sp_curr_thread;
|
|
RETURN_IF_FAIL(GetCurrentThread(sp_host_context, &sp_curr_thread));
|
|
|
|
WRL::ComPtr<IModelObject> sp_environment, sp_environment_block;
|
|
WRL::ComPtr<IModelObject> sp_tls_slots, sp_slot_index, sp_isolate_ptr;
|
|
RETURN_IF_FAIL(
|
|
sp_curr_thread->GetKeyValue(L"Environment", &sp_environment, nullptr));
|
|
|
|
RETURN_IF_FAIL(sp_environment->GetKeyValue(L"EnvironmentBlock",
|
|
&sp_environment_block, nullptr));
|
|
|
|
// EnvironmentBlock and TlsSlots are native types (TypeUDT) and thus
|
|
// GetRawValue rather than GetKeyValue should be used to get field (member)
|
|
// values.
|
|
ModelObjectKind kind;
|
|
RETURN_IF_FAIL(sp_environment_block->GetKind(&kind));
|
|
if (kind != ModelObjectKind::ObjectTargetObject) return E_FAIL;
|
|
|
|
RETURN_IF_FAIL(sp_environment_block->GetRawValue(SymbolField, L"TlsSlots", 0,
|
|
&sp_tls_slots));
|
|
|
|
int isolate_key = -1;
|
|
RETURN_IF_FAIL(GetIsolateKey(sp_host_context, &isolate_key));
|
|
RETURN_IF_FAIL(CreateInt32(isolate_key, &sp_slot_index));
|
|
|
|
RETURN_IF_FAIL(GetModelAtIndex(sp_tls_slots, sp_slot_index, &sp_isolate_ptr));
|
|
|
|
// Need to dereference the slot and then get the address held in it
|
|
WRL::ComPtr<IModelObject> sp_dereferenced_slot;
|
|
RETURN_IF_FAIL(sp_isolate_ptr->Dereference(&sp_dereferenced_slot));
|
|
|
|
uint64_t isolate_ptr;
|
|
RETURN_IF_FAIL(UnboxULong64(sp_dereferenced_slot.Get(), &isolate_ptr));
|
|
Location isolate_addr{isolate_ptr};
|
|
|
|
// If we got the isolate_key OK, then must have the V8 module loaded
|
|
// Get the internal Isolate type from it
|
|
WRL::ComPtr<IDebugHostType> sp_isolate_type, sp_isolate_ptr_type;
|
|
RETURN_IF_FAIL(Extension::Current()
|
|
->GetV8Module(sp_host_context)
|
|
->FindTypeByName(kIsolate, &sp_isolate_type));
|
|
RETURN_IF_FAIL(
|
|
sp_isolate_type->CreatePointerTo(PointerStandard, &sp_isolate_ptr_type));
|
|
|
|
RETURN_IF_FAIL(sp_data_model_manager->CreateTypedObject(
|
|
sp_host_context.Get(), isolate_addr, sp_isolate_type.Get(), &sp_result));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
IFACEMETHODIMP CurrIsolateAlias::Call(IModelObject* p_context_object,
|
|
ULONG64 arg_count,
|
|
IModelObject** pp_arguments,
|
|
IModelObject** pp_result,
|
|
IKeyStore** pp_metadata) noexcept {
|
|
*pp_result = nullptr;
|
|
WRL::ComPtr<IModelObject> sp_result;
|
|
RETURN_IF_FAIL(GetCurrentIsolate(sp_result));
|
|
*pp_result = sp_result.Detach();
|
|
return S_OK;
|
|
}
|