11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci// This file defines the public interface to v8_debug_helper. 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#ifndef V8_TOOLS_DEBUG_HELPER_DEBUG_HELPER_H_ 81cb0ef41Sopenharmony_ci#define V8_TOOLS_DEBUG_HELPER_DEBUG_HELPER_H_ 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#include <cstdint> 111cb0ef41Sopenharmony_ci#include <memory> 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci#if defined(_WIN32) 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci#ifdef BUILDING_V8_DEBUG_HELPER 161cb0ef41Sopenharmony_ci#define V8_DEBUG_HELPER_EXPORT __declspec(dllexport) 171cb0ef41Sopenharmony_ci#elif USING_V8_DEBUG_HELPER 181cb0ef41Sopenharmony_ci#define V8_DEBUG_HELPER_EXPORT __declspec(dllimport) 191cb0ef41Sopenharmony_ci#else 201cb0ef41Sopenharmony_ci#define V8_DEBUG_HELPER_EXPORT 211cb0ef41Sopenharmony_ci#endif 221cb0ef41Sopenharmony_ci 231cb0ef41Sopenharmony_ci#else // defined(_WIN32) 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci#ifdef BUILDING_V8_DEBUG_HELPER 261cb0ef41Sopenharmony_ci#define V8_DEBUG_HELPER_EXPORT __attribute__((visibility("default"))) 271cb0ef41Sopenharmony_ci#else 281cb0ef41Sopenharmony_ci#define V8_DEBUG_HELPER_EXPORT 291cb0ef41Sopenharmony_ci#endif 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci#endif // defined(_WIN32) 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_cinamespace v8 { 341cb0ef41Sopenharmony_cinamespace debug_helper { 351cb0ef41Sopenharmony_ci 361cb0ef41Sopenharmony_ci// Possible results when attempting to fetch memory from the debuggee. 371cb0ef41Sopenharmony_cienum class MemoryAccessResult { 381cb0ef41Sopenharmony_ci kOk, 391cb0ef41Sopenharmony_ci kAddressNotValid, 401cb0ef41Sopenharmony_ci kAddressValidButInaccessible, // Possible in incomplete dump. 411cb0ef41Sopenharmony_ci}; 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci// Information about how this tool discovered the type of the object. 441cb0ef41Sopenharmony_cienum class TypeCheckResult { 451cb0ef41Sopenharmony_ci // Success cases: 461cb0ef41Sopenharmony_ci kSmi, 471cb0ef41Sopenharmony_ci kWeakRef, 481cb0ef41Sopenharmony_ci kUsedMap, 491cb0ef41Sopenharmony_ci kKnownMapPointer, 501cb0ef41Sopenharmony_ci kUsedTypeHint, 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci // Failure cases: 531cb0ef41Sopenharmony_ci kUnableToDecompress, // Caller must provide the heap range somehow. 541cb0ef41Sopenharmony_ci kObjectPointerInvalid, 551cb0ef41Sopenharmony_ci kObjectPointerValidButInaccessible, // Possible in incomplete dump. 561cb0ef41Sopenharmony_ci kMapPointerInvalid, 571cb0ef41Sopenharmony_ci kMapPointerValidButInaccessible, // Possible in incomplete dump. 581cb0ef41Sopenharmony_ci kUnknownInstanceType, 591cb0ef41Sopenharmony_ci kUnknownTypeHint, 601cb0ef41Sopenharmony_ci}; 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_cienum class PropertyKind { 631cb0ef41Sopenharmony_ci kSingle, 641cb0ef41Sopenharmony_ci kArrayOfKnownSize, 651cb0ef41Sopenharmony_ci kArrayOfUnknownSizeDueToInvalidMemory, 661cb0ef41Sopenharmony_ci kArrayOfUnknownSizeDueToValidButInaccessibleMemory, 671cb0ef41Sopenharmony_ci}; 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_cistruct PropertyBase { 701cb0ef41Sopenharmony_ci const char* name; 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci // Statically-determined type, such as from .tq definition. Can be an empty 731cb0ef41Sopenharmony_ci // string if this property is itself a Torque-defined struct; in that case use 741cb0ef41Sopenharmony_ci // |struct_fields| instead. This type should be treated as if it were used in 751cb0ef41Sopenharmony_ci // the v8::internal namespace; that is, type "X::Y" can mean any of the 761cb0ef41Sopenharmony_ci // following, in order of decreasing preference: 771cb0ef41Sopenharmony_ci // - v8::internal::X::Y 781cb0ef41Sopenharmony_ci // - v8::X::Y 791cb0ef41Sopenharmony_ci // - X::Y 801cb0ef41Sopenharmony_ci const char* type; 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci // In some cases, |type| may be a simple type representing a compressed 831cb0ef41Sopenharmony_ci // pointer such as v8::internal::TaggedValue. In those cases, 841cb0ef41Sopenharmony_ci // |decompressed_type| will contain the type of the object when decompressed. 851cb0ef41Sopenharmony_ci // Otherwise, |decompressed_type| will match |type|. In any case, it is safe 861cb0ef41Sopenharmony_ci // to pass the |decompressed_type| value as the type_hint on a subsequent call 871cb0ef41Sopenharmony_ci // to GetObjectProperties. 881cb0ef41Sopenharmony_ci const char* decompressed_type; 891cb0ef41Sopenharmony_ci}; 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_cistruct StructProperty : public PropertyBase { 921cb0ef41Sopenharmony_ci // The offset from the beginning of the struct to this field. 931cb0ef41Sopenharmony_ci size_t offset; 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci // The number of bits that are present, if this value is a bitfield. Zero 961cb0ef41Sopenharmony_ci // indicates that this value is not a bitfield (the full value is stored). 971cb0ef41Sopenharmony_ci uint8_t num_bits; 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci // The number of bits by which this value has been left-shifted for storage as 1001cb0ef41Sopenharmony_ci // a bitfield. 1011cb0ef41Sopenharmony_ci uint8_t shift_bits; 1021cb0ef41Sopenharmony_ci}; 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_cistruct ObjectProperty : public PropertyBase { 1051cb0ef41Sopenharmony_ci // The address where the property value can be found in the debuggee's address 1061cb0ef41Sopenharmony_ci // space, or the address of the first value for an array. 1071cb0ef41Sopenharmony_ci uintptr_t address; 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci // If kind indicates an array of unknown size, num_values will be 0 and debug 1101cb0ef41Sopenharmony_ci // tools should display this property as a raw pointer. Note that there is a 1111cb0ef41Sopenharmony_ci // semantic difference between num_values=1 and kind=kSingle (normal property) 1121cb0ef41Sopenharmony_ci // versus num_values=1 and kind=kArrayOfKnownSize (one-element array). 1131cb0ef41Sopenharmony_ci size_t num_values; 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci // The number of bytes occupied by a single instance of the value type for 1161cb0ef41Sopenharmony_ci // this property. This can also be used as the array stride because arrays are 1171cb0ef41Sopenharmony_ci // tightly packed like in C. 1181cb0ef41Sopenharmony_ci size_t size; 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci // If the property is a struct made up of several pieces of data packed 1211cb0ef41Sopenharmony_ci // together, then the |struct_fields| array contains descriptions of those 1221cb0ef41Sopenharmony_ci // fields. 1231cb0ef41Sopenharmony_ci size_t num_struct_fields; 1241cb0ef41Sopenharmony_ci StructProperty** struct_fields; 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci PropertyKind kind; 1271cb0ef41Sopenharmony_ci}; 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_cistruct ObjectPropertiesResult { 1301cb0ef41Sopenharmony_ci TypeCheckResult type_check_result; 1311cb0ef41Sopenharmony_ci const char* brief; 1321cb0ef41Sopenharmony_ci const char* type; // Runtime type of the object. 1331cb0ef41Sopenharmony_ci size_t num_properties; 1341cb0ef41Sopenharmony_ci ObjectProperty** properties; 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci // If not all relevant memory is available, GetObjectProperties may respond 1371cb0ef41Sopenharmony_ci // with a technically correct but uninteresting type such as HeapObject, and 1381cb0ef41Sopenharmony_ci // use other heuristics to make reasonable guesses about what specific type 1391cb0ef41Sopenharmony_ci // the object actually is. You may request data about the same object again 1401cb0ef41Sopenharmony_ci // using any of these guesses as the type hint, but the results should be 1411cb0ef41Sopenharmony_ci // formatted to the user in a way that clearly indicates that they're only 1421cb0ef41Sopenharmony_ci // guesses. 1431cb0ef41Sopenharmony_ci size_t num_guessed_types; 1441cb0ef41Sopenharmony_ci const char** guessed_types; 1451cb0ef41Sopenharmony_ci}; 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_cistruct StackFrameResult { 1481cb0ef41Sopenharmony_ci size_t num_properties; 1491cb0ef41Sopenharmony_ci ObjectProperty** properties; 1501cb0ef41Sopenharmony_ci}; 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci// Copies byte_count bytes of memory from the given address in the debuggee to 1531cb0ef41Sopenharmony_ci// the destination buffer. 1541cb0ef41Sopenharmony_citypedef MemoryAccessResult (*MemoryAccessor)(uintptr_t address, 1551cb0ef41Sopenharmony_ci void* destination, 1561cb0ef41Sopenharmony_ci size_t byte_count); 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci// Additional data that can help GetObjectProperties to be more accurate. Any 1591cb0ef41Sopenharmony_ci// fields you don't know can be set to zero and this library will do the best it 1601cb0ef41Sopenharmony_ci// can with the information available. 1611cb0ef41Sopenharmony_cistruct HeapAddresses { 1621cb0ef41Sopenharmony_ci // Beginning of allocated space for various kinds of data. These can help us 1631cb0ef41Sopenharmony_ci // to detect certain common objects that are placed in memory during startup. 1641cb0ef41Sopenharmony_ci // These values might be provided via name-value pairs in CrashPad dumps. 1651cb0ef41Sopenharmony_ci // Otherwise, they can be obtained as follows: 1661cb0ef41Sopenharmony_ci // 1. Get the Isolate pointer for the current thread. It might be somewhere on 1671cb0ef41Sopenharmony_ci // the stack, or it might be accessible from thread-local storage with the 1681cb0ef41Sopenharmony_ci // key stored in v8::internal::Isolate::isolate_key_. 1691cb0ef41Sopenharmony_ci // 2. Get isolate->heap_.map_space_->memory_chunk_list_.front_ and similar for 1701cb0ef41Sopenharmony_ci // old_space_ and read_only_space_. 1711cb0ef41Sopenharmony_ci uintptr_t map_space_first_page; 1721cb0ef41Sopenharmony_ci uintptr_t old_space_first_page; 1731cb0ef41Sopenharmony_ci uintptr_t read_only_space_first_page; 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci // Any valid heap pointer address. On platforms where pointer compression is 1761cb0ef41Sopenharmony_ci // enabled, this can allow us to get data from compressed pointers even if the 1771cb0ef41Sopenharmony_ci // other data above is not provided. The Isolate pointer is valid for this 1781cb0ef41Sopenharmony_ci // purpose if you have it. 1791cb0ef41Sopenharmony_ci uintptr_t any_heap_pointer; 1801cb0ef41Sopenharmony_ci}; 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci// Result type for ListObjectClasses. 1831cb0ef41Sopenharmony_cistruct ClassList { 1841cb0ef41Sopenharmony_ci size_t num_class_names; 1851cb0ef41Sopenharmony_ci const char* const* class_names; // Fully qualified class names. 1861cb0ef41Sopenharmony_ci}; 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_ci} // namespace debug_helper 1891cb0ef41Sopenharmony_ci} // namespace v8 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ciextern "C" { 1921cb0ef41Sopenharmony_ci// Raw library interface. If possible, use functions in v8::debug_helper 1931cb0ef41Sopenharmony_ci// namespace instead because they use smart pointers to prevent leaks. 1941cb0ef41Sopenharmony_ciV8_DEBUG_HELPER_EXPORT v8::debug_helper::ObjectPropertiesResult* 1951cb0ef41Sopenharmony_ci_v8_debug_helper_GetObjectProperties( 1961cb0ef41Sopenharmony_ci uintptr_t object, v8::debug_helper::MemoryAccessor memory_accessor, 1971cb0ef41Sopenharmony_ci const v8::debug_helper::HeapAddresses& heap_addresses, 1981cb0ef41Sopenharmony_ci const char* type_hint); 1991cb0ef41Sopenharmony_ciV8_DEBUG_HELPER_EXPORT void _v8_debug_helper_Free_ObjectPropertiesResult( 2001cb0ef41Sopenharmony_ci v8::debug_helper::ObjectPropertiesResult* result); 2011cb0ef41Sopenharmony_ciV8_DEBUG_HELPER_EXPORT v8::debug_helper::StackFrameResult* 2021cb0ef41Sopenharmony_ci_v8_debug_helper_GetStackFrame( 2031cb0ef41Sopenharmony_ci uintptr_t frame_pointer, v8::debug_helper::MemoryAccessor memory_accessor); 2041cb0ef41Sopenharmony_ciV8_DEBUG_HELPER_EXPORT void _v8_debug_helper_Free_StackFrameResult( 2051cb0ef41Sopenharmony_ci v8::debug_helper::StackFrameResult* result); 2061cb0ef41Sopenharmony_ciV8_DEBUG_HELPER_EXPORT const v8::debug_helper::ClassList* 2071cb0ef41Sopenharmony_ci_v8_debug_helper_ListObjectClasses(); 2081cb0ef41Sopenharmony_ciV8_DEBUG_HELPER_EXPORT const char* _v8_debug_helper_BitsetName( 2091cb0ef41Sopenharmony_ci uint64_t payload); 2101cb0ef41Sopenharmony_ci} 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_cinamespace v8 { 2131cb0ef41Sopenharmony_cinamespace debug_helper { 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_cistruct DebugHelperObjectPropertiesResultDeleter { 2161cb0ef41Sopenharmony_ci void operator()(v8::debug_helper::ObjectPropertiesResult* ptr) { 2171cb0ef41Sopenharmony_ci _v8_debug_helper_Free_ObjectPropertiesResult(ptr); 2181cb0ef41Sopenharmony_ci } 2191cb0ef41Sopenharmony_ci}; 2201cb0ef41Sopenharmony_ciusing ObjectPropertiesResultPtr = 2211cb0ef41Sopenharmony_ci std::unique_ptr<ObjectPropertiesResult, 2221cb0ef41Sopenharmony_ci DebugHelperObjectPropertiesResultDeleter>; 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci// Get information about the given object pointer, which could be: 2251cb0ef41Sopenharmony_ci// - A tagged pointer, strong or weak 2261cb0ef41Sopenharmony_ci// - A cleared weak pointer 2271cb0ef41Sopenharmony_ci// - A compressed tagged pointer, zero-extended to 64 bits 2281cb0ef41Sopenharmony_ci// - A tagged small integer 2291cb0ef41Sopenharmony_ci// The type hint is only used if the object's Map is missing or corrupt. It 2301cb0ef41Sopenharmony_ci// should be the fully-qualified name of a class that inherits from 2311cb0ef41Sopenharmony_ci// v8::internal::Object. 2321cb0ef41Sopenharmony_ciinline ObjectPropertiesResultPtr GetObjectProperties( 2331cb0ef41Sopenharmony_ci uintptr_t object, v8::debug_helper::MemoryAccessor memory_accessor, 2341cb0ef41Sopenharmony_ci const HeapAddresses& heap_addresses, const char* type_hint = nullptr) { 2351cb0ef41Sopenharmony_ci return ObjectPropertiesResultPtr(_v8_debug_helper_GetObjectProperties( 2361cb0ef41Sopenharmony_ci object, memory_accessor, heap_addresses, type_hint)); 2371cb0ef41Sopenharmony_ci} 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ci// Get a list of all class names deriving from v8::internal::Object. 2401cb0ef41Sopenharmony_ciinline const ClassList* ListObjectClasses() { 2411cb0ef41Sopenharmony_ci return _v8_debug_helper_ListObjectClasses(); 2421cb0ef41Sopenharmony_ci} 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_ci// Return a bitset name for a v8::internal::compiler::Type with payload or null 2451cb0ef41Sopenharmony_ci// if the payload is not a bitset. 2461cb0ef41Sopenharmony_ciinline const char* BitsetName(uint64_t payload) { 2471cb0ef41Sopenharmony_ci return _v8_debug_helper_BitsetName(payload); 2481cb0ef41Sopenharmony_ci} 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_cistruct DebugHelperStackFrameResultDeleter { 2511cb0ef41Sopenharmony_ci void operator()(v8::debug_helper::StackFrameResult* ptr) { 2521cb0ef41Sopenharmony_ci _v8_debug_helper_Free_StackFrameResult(ptr); 2531cb0ef41Sopenharmony_ci } 2541cb0ef41Sopenharmony_ci}; 2551cb0ef41Sopenharmony_ciusing StackFrameResultPtr = 2561cb0ef41Sopenharmony_ci std::unique_ptr<StackFrameResult, DebugHelperStackFrameResultDeleter>; 2571cb0ef41Sopenharmony_ci 2581cb0ef41Sopenharmony_ciinline StackFrameResultPtr GetStackFrame( 2591cb0ef41Sopenharmony_ci uintptr_t frame_pointer, v8::debug_helper::MemoryAccessor memory_accessor) { 2601cb0ef41Sopenharmony_ci return StackFrameResultPtr( 2611cb0ef41Sopenharmony_ci _v8_debug_helper_GetStackFrame(frame_pointer, memory_accessor)); 2621cb0ef41Sopenharmony_ci} 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci} // namespace debug_helper 2651cb0ef41Sopenharmony_ci} // namespace v8 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci#endif 268