diff options
Diffstat (limited to 'src/ToolBox/SOS/lldbplugin')
-rw-r--r-- | src/ToolBox/SOS/lldbplugin/CMakeLists.txt | 150 | ||||
-rw-r--r-- | src/ToolBox/SOS/lldbplugin/inc/lldbservices.h | 550 | ||||
-rw-r--r-- | src/ToolBox/SOS/lldbplugin/mstypes.h | 27 | ||||
-rw-r--r-- | src/ToolBox/SOS/lldbplugin/services.cpp | 1746 | ||||
-rw-r--r-- | src/ToolBox/SOS/lldbplugin/services.h | 274 | ||||
-rw-r--r-- | src/ToolBox/SOS/lldbplugin/setclrpathcommand.cpp | 53 | ||||
-rw-r--r-- | src/ToolBox/SOS/lldbplugin/setsostidcommand.cpp | 64 | ||||
-rw-r--r-- | src/ToolBox/SOS/lldbplugin/soscommand.cpp | 157 | ||||
-rw-r--r-- | src/ToolBox/SOS/lldbplugin/sosplugin.cpp | 18 | ||||
-rw-r--r-- | src/ToolBox/SOS/lldbplugin/sosplugin.h | 25 |
10 files changed, 0 insertions, 3064 deletions
diff --git a/src/ToolBox/SOS/lldbplugin/CMakeLists.txt b/src/ToolBox/SOS/lldbplugin/CMakeLists.txt deleted file mode 100644 index 6a279edc8a..0000000000 --- a/src/ToolBox/SOS/lldbplugin/CMakeLists.txt +++ /dev/null @@ -1,150 +0,0 @@ -project(sosplugin) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -# Set the RPATH of sos so that it can find dependencies without needing to set LD_LIBRARY_PATH -# For more information: http://www.cmake.org/Wiki/CMake_RPATH_handling. -if (CORECLR_SET_RPATH) - set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) - if(CLR_CMAKE_PLATFORM_DARWIN) - set(CMAKE_INSTALL_RPATH "@loader_path") - else() - set(CMAKE_INSTALL_RPATH "\$ORIGIN") - endif(CLR_CMAKE_PLATFORM_DARWIN) -endif (CORECLR_SET_RPATH) - -add_definitions(-DPAL_STDCPP_COMPAT) - -if (CLR_CMAKE_PLATFORM_LINUX OR CLR_CMAKE_PLATFORM_FREEBSD) - set(PLATFORM_SUPPORTS_LLDB_PLUGIN true) -endif() - -set(ENABLE_LLDBPLUGIN ${PLATFORM_SUPPORTS_LLDB_PLUGIN} CACHE BOOL "Enable building the SOS plugin for LLDB.") -set(REQUIRE_LLDBPLUGIN ${PLATFORM_SUPPORTS_LLDB_PLUGIN} CACHE BOOL "Require building the SOS plugin for LLDB.") - -if(SKIP_LLDBPLUGIN) - SET(REQUIRE_LLDBPLUGIN false) -endif() - -if(CLR_CMAKE_PLATFORM_ARCH_AMD64) - add_definitions(-D_TARGET_AMD64_) - add_definitions(-DDBG_TARGET_64BIT) - add_definitions(-DDBG_TARGET_AMD64) - add_definitions(-DDBG_TARGET_WIN64) - add_definitions(-DBIT64) -elseif(CLR_CMAKE_PLATFORM_ARCH_I386) - add_definitions(-D_TARGET_X86_) - add_definitions(-DDBG_TARGET_32BIT) - add_definitions(-DDBG_TARGET_X86) -elseif(CLR_CMAKE_PLATFORM_ARCH_ARM) - add_definitions(-D_TARGET_ARM_) - add_definitions(-DDBG_TARGET_32BIT) - add_definitions(-DDBG_TARGET_ARM) -elseif(CLR_CMAKE_PLATFORM_ARCH_ARM64) - add_definitions(-D_TARGET_ARM64_) - add_definitions(-DDBG_TARGET_64BIT) - add_definitions(-DDBG_TARGET_ARM64) - add_definitions(-DDBG_TARGET_WIN64) - add_definitions(-DBIT64) - SET(REQUIRE_LLDBPLUGIN false) -endif() - -if(NOT $ENV{LLVM_HOME} STREQUAL "") - set(LLDB_INCLUDE_DIR "$ENV{LLVM_HOME}/include") - set(LLDB_LIB_DIR "$ENV{LLVM_HOME}/lib") -else() - if(NOT $ENV{LLDB_INCLUDE_DIR} STREQUAL "") - set(LLDB_INCLUDE_DIR "$ENV{LLDB_INCLUDE_DIR}") - endif() - if(NOT $ENV{LLDB_LIB_DIR} STREQUAL "") - set(LLDB_LIB_DIR "$ENV{LLDB_LIB_DIR}") - endif() -endif() - -if(NOT ENABLE_LLDBPLUGIN) - return() -endif() - -if(NOT $ENV{LLDB_LIB} STREQUAL "") - set(LLDB_LIB "$ENV{LLDB_LIB}") -else() - # Check for LLDB library - if(CLR_CMAKE_PLATFORM_DARWIN) - find_library(LLDB_LIB NAMES LLDB lldb lldb-7 lldb-6.0 lldb-5.0 lldb-4.0 lldb-3.9 lldb-3.8 lldb-3.7 lldb-3.6 lldb-3.5 PATHS "${LLDB_LIB_DIR}" PATH_SUFFIXES llvm NO_DEFAULT_PATH) - find_library(LLDB_LIB NAMES LLDB lldb lldb-7 lldb-6.0 lldb-5.0 lldb-4.0 lldb-3.9 lldb-3.8 lldb-3.7 lldb-3.6 lldb-3.5 PATH_SUFFIXES llvm) - if(LLDB_LIB STREQUAL LLDB_LIB-NOTFOUND) - if(REQUIRE_LLDBPLUGIN) - set(MESSAGE_MODE FATAL_ERROR) - else() - set(MESSAGE_MODE WARNING) - endif() - message(${MESSAGE_MODE} "Cannot find lldb library. Try installing Xcode. You may need to set LLVM_HOME, LLDB_LIB_DIR or LLDB_LIB if the build still can't find it.") - return() - endif() - endif() -endif() - -message(STATUS "LLDB_LIB: ${LLDB_LIB}") - -if(NOT $ENV{LLDB_H} STREQUAL "") - set(LLDB_H "$ENV{LLDB_H}") -else() - # Check for LLDB headers - # Multiple versions of LLDB can install side-by-side, so we need to check for lldb in various locations. - # If the file in a directory is found the result is stored in the variable and the search will not be repeated unless the variable is cleared. - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "${LLDB_INCLUDE_DIR}" NO_DEFAULT_PATH) - find_path(LLDB_H "lldb/API/LLDB.h") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-7/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-6.0/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-5.0/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-4.0/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-3.9/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-3.8/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-3.7/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-3.6/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-3.5/include") - #FreeBSD - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/local/llvm70/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/local/llvm60/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/local/llvm50/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/local/llvm40/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/local/llvm39/include") - find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/local/llvm38/include") - - if(LLDB_H STREQUAL LLDB_H-NOTFOUND) - if(REQUIRE_LLDBPLUGIN) - set(MESSAGE_MODE FATAL_ERROR) - else() - set(MESSAGE_MODE WARNING) - endif() - message(${MESSAGE_MODE} "Cannot find LLDB.h Try installing lldb-3.9-dev (or the appropriate package for your platform). You may need to set LLVM_HOME or LLDB_INCLUDE_DIR if the build still can't find it.") - return() - endif() -endif() - -message(STATUS "LLDB_H: ${LLDB_H}") - -include_directories(inc) -include_directories("${LLDB_H}") -include_directories(${CLR_DIR}/src/debug/inc) -include_directories(${CLR_DIR}/src/inc) -include_directories(${CLR_DIR}/src/pal/inc) -include_directories(${CLR_DIR}/src/pal/inc/rt) - -set(SOURCES - sosplugin.cpp - soscommand.cpp - setclrpathcommand.cpp - setsostidcommand.cpp - services.cpp -) - -_add_library(sosplugin SHARED ${SOURCES}) -add_dependencies(sosplugin sos) - -if (CLR_CMAKE_PLATFORM_DARWIN) - target_link_libraries(sosplugin ${LLDB_LIB}) -endif() - -# add the install targets -install_clr(sosplugin) diff --git a/src/ToolBox/SOS/lldbplugin/inc/lldbservices.h b/src/ToolBox/SOS/lldbplugin/inc/lldbservices.h deleted file mode 100644 index 7bb9b1aca3..0000000000 --- a/src/ToolBox/SOS/lldbplugin/inc/lldbservices.h +++ /dev/null @@ -1,550 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -//---------------------------------------------------------------------------- -// -// LLDB debugger services for sos -// -//---------------------------------------------------------------------------- - -#ifndef __LLDBSERVICES_H__ -#define __LLDBSERVICES_H__ - -#include <stdarg.h> -#include <palrt.h> -#include <unknwn.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// Output mask bits. -// Normal output. -#define DEBUG_OUTPUT_NORMAL 0x00000001 -// Error output. -#define DEBUG_OUTPUT_ERROR 0x00000002 -// Warnings. -#define DEBUG_OUTPUT_WARNING 0x00000004 -// Additional output. -#define DEBUG_OUTPUT_VERBOSE 0x00000008 -// Prompt output. -#define DEBUG_OUTPUT_PROMPT 0x00000010 -// Register dump before prompt. -#define DEBUG_OUTPUT_PROMPT_REGISTERS 0x00000020 -// Warnings specific to extension operation. -#define DEBUG_OUTPUT_EXTENSION_WARNING 0x00000040 -// Debuggee debug output, such as from OutputDebugString. -#define DEBUG_OUTPUT_DEBUGGEE 0x00000080 -// Debuggee-generated prompt, such as from DbgPrompt. -#define DEBUG_OUTPUT_DEBUGGEE_PROMPT 0x00000100 -// Symbol messages, such as for !sym noisy. -#define DEBUG_OUTPUT_SYMBOLS 0x00000200 - -// Execute and ExecuteCommandFile flags. -// These flags only apply to the command -// text itself; output from the executed -// command is controlled by the output -// control parameter. -// Default execution. Command is logged -// but not output. -#define DEBUG_EXECUTE_DEFAULT 0x00000000 -// Echo commands during execution. In -// ExecuteCommandFile also echoes the prompt -// for each line of the file. -#define DEBUG_EXECUTE_ECHO 0x00000001 -// Do not log or output commands during execution. -// Overridden by DEBUG_EXECUTE_ECHO. -#define DEBUG_EXECUTE_NOT_LOGGED 0x00000002 -// If this flag is not set an empty string -// to Execute will repeat the last Execute -// string. -#define DEBUG_EXECUTE_NO_REPEAT 0x00000004 - -// Classes of debuggee. Each class -// has different qualifiers for specific -// kinds of debuggees. -#define DEBUG_CLASS_UNINITIALIZED 0 -#define DEBUG_CLASS_KERNEL 1 -#define DEBUG_CLASS_USER_WINDOWS 2 -#define DEBUG_CLASS_IMAGE_FILE 3 - -// Generic dump types. These can be used -// with either user or kernel sessions. -// Session-type-specific aliases are also -// provided. -#define DEBUG_DUMP_SMALL 1024 -#define DEBUG_DUMP_DEFAULT 1025 -#define DEBUG_DUMP_FULL 1026 -#define DEBUG_DUMP_IMAGE_FILE 1027 -#define DEBUG_DUMP_TRACE_LOG 1028 -#define DEBUG_DUMP_WINDOWS_CE 1029 - -#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. -#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian -#define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) -#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian - -// Execution status codes used for waiting, -// for returning current status and for -// event method return values. -#define DEBUG_STATUS_NO_CHANGE 0 -#define DEBUG_STATUS_GO 1 -#define DEBUG_STATUS_GO_HANDLED 2 -#define DEBUG_STATUS_GO_NOT_HANDLED 3 -#define DEBUG_STATUS_STEP_OVER 4 -#define DEBUG_STATUS_STEP_INTO 5 -#define DEBUG_STATUS_BREAK 6 -#define DEBUG_STATUS_NO_DEBUGGEE 7 -#define DEBUG_STATUS_STEP_BRANCH 8 -#define DEBUG_STATUS_IGNORE_EVENT 9 -#define DEBUG_STATUS_RESTART_REQUESTED 10 -#define DEBUG_STATUS_REVERSE_GO 11 -#define DEBUG_STATUS_REVERSE_STEP_BRANCH 12 -#define DEBUG_STATUS_REVERSE_STEP_OVER 13 -#define DEBUG_STATUS_REVERSE_STEP_INTO 14 -#define DEBUG_STATUS_OUT_OF_SYNC 15 -#define DEBUG_STATUS_WAIT_INPUT 16 -#define DEBUG_STATUS_TIMEOUT 17 - -#define DEBUG_STATUS_MASK 0x1f - -#define DEBUG_EVENT_EXCEPTION 0x00000002 - -typedef struct _DEBUG_LAST_EVENT_INFO_EXCEPTION -{ - EXCEPTION_RECORD64 ExceptionRecord; - ULONG FirstChance; -} DEBUG_LAST_EVENT_INFO_EXCEPTION, *PDEBUG_LAST_EVENT_INFO_EXCEPTION; - -// -// Information about a module. -// - -// Flags. -#define DEBUG_MODULE_LOADED 0x00000000 -#define DEBUG_MODULE_UNLOADED 0x00000001 -#define DEBUG_MODULE_USER_MODE 0x00000002 -#define DEBUG_MODULE_EXPLICIT 0x00000008 -#define DEBUG_MODULE_SECONDARY 0x00000010 -#define DEBUG_MODULE_SYNTHETIC 0x00000020 -#define DEBUG_MODULE_SYM_BAD_CHECKSUM 0x00010000 - -// Symbol types. -#define DEBUG_SYMTYPE_NONE 0 -#define DEBUG_SYMTYPE_COFF 1 -#define DEBUG_SYMTYPE_CODEVIEW 2 -#define DEBUG_SYMTYPE_PDB 3 -#define DEBUG_SYMTYPE_EXPORT 4 -#define DEBUG_SYMTYPE_DEFERRED 5 -#define DEBUG_SYMTYPE_SYM 6 -#define DEBUG_SYMTYPE_DIA 7 - -typedef struct _DEBUG_MODULE_PARAMETERS -{ - ULONG64 Base; - ULONG Size; - ULONG TimeDateStamp; - ULONG Checksum; - ULONG Flags; - ULONG SymbolType; - ULONG ImageNameSize; - ULONG ModuleNameSize; - ULONG LoadedImageNameSize; - ULONG SymbolFileNameSize; - ULONG MappedImageNameSize; - ULONG64 Reserved[2]; -} DEBUG_MODULE_PARAMETERS, *PDEBUG_MODULE_PARAMETERS; - -// FindSourceFile flags. -#define DEBUG_FIND_SOURCE_DEFAULT 0x00000000 -// Returns fully-qualified paths only. If this -// is not set the path returned may be relative. -#define DEBUG_FIND_SOURCE_FULL_PATH 0x00000001 -// Scans all the path elements for a match and -// returns the one that has the most similarity -// between the given file and the matching element. -#define DEBUG_FIND_SOURCE_BEST_MATCH 0x00000002 -// Do not search source server paths. -#define DEBUG_FIND_SOURCE_NO_SRCSRV 0x00000004 -// Restrict FindSourceFileAndToken to token lookup only. -#define DEBUG_FIND_SOURCE_TOKEN_LOOKUP 0x00000008 - -// A special value marking an offset that should not -// be treated as a valid offset. This is only used -// in special situations where it is unlikely that -// this value would be a valid offset. -#define DEBUG_INVALID_OFFSET ((ULONG64)-1) - -// General unspecified ID constant. -#define DEBUG_ANY_ID 0xffffffff - -typedef struct _DEBUG_STACK_FRAME -{ - ULONG64 InstructionOffset; - ULONG64 ReturnOffset; - ULONG64 FrameOffset; - ULONG64 StackOffset; - ULONG64 FuncTableEntry; - ULONG64 Params[4]; - ULONG64 Reserved[6]; - BOOL Virtual; - ULONG FrameNumber; -} DEBUG_STACK_FRAME, *PDEBUG_STACK_FRAME; - -#define DBG_FRAME_DEFAULT 0 // the same as INLINE_FRAME_CONTEXT_INIT in dbghelp.h -#define DBG_FRAME_IGNORE_INLINE 0xFFFFFFFF // the same as INLINE_FRAME_CONTEXT_IGNORE in dbghelp.h - -typedef struct _DEBUG_STACK_FRAME_EX -{ - // First DEBUG_STACK_FRAME structure - ULONG64 InstructionOffset; - ULONG64 ReturnOffset; - ULONG64 FrameOffset; - ULONG64 StackOffset; - ULONG64 FuncTableEntry; - ULONG64 Params[4]; - ULONG64 Reserved[6]; - BOOL Virtual; - ULONG FrameNumber; - - // Extended DEBUG_STACK_FRAME fields. - ULONG InlineFrameContext; - ULONG Reserved1; // For alignment purpose. -} DEBUG_STACK_FRAME_EX, *PDEBUG_STACK_FRAME_EX; - -// The types of inline frame context. -#define STACK_FRAME_TYPE_INIT 0x00 -#define STACK_FRAME_TYPE_STACK 0x01 -#define STACK_FRAME_TYPE_INLINE 0x02 -#define STACK_FRAME_TYPE_RA 0x80 // Whether the instruction pointer is the current IP or a RA from callee frame. -#define STACK_FRAME_TYPE_IGNORE 0xFF - -// -// options that are set/returned by SymSetOptions() & SymGetOptions() -// these are used as a mask -// -#define SYMOPT_LOAD_LINES 0x00000010 - -interface ILLDBServices; -typedef HRESULT (*PFN_EXCEPTION_CALLBACK)(ILLDBServices *services); - -//---------------------------------------------------------------------------- -// ILLDBServices -//---------------------------------------------------------------------------- - -MIDL_INTERFACE("2E6C569A-9E14-4DA4-9DFC-CDB73A532566") -ILLDBServices : public IUnknown -{ -public: - - //---------------------------------------------------------------------------- - // ILLDBServices - //---------------------------------------------------------------------------- - - // Returns the coreclr module directory found by lldb plugin - // in the target process. - virtual PCSTR GetCoreClrDirectory() = 0; - - // Evaluates a lldb expression into a value. - virtual DWORD_PTR GetExpression( - /* [in] */ PCSTR exp) = 0; - - // Unwind one native stack frame given a thread and register context - virtual HRESULT VirtualUnwind( - /* [in] */ DWORD threadID, - /* [in] */ ULONG32 contextSize, - /* [in, out, size_is(contextSize)] */ PBYTE context) = 0; - - // Set an exception throw callback - virtual HRESULT SetExceptionCallback( - /* [in] */ PFN_EXCEPTION_CALLBACK callback) = 0; - - // Clear the exception throw callback - virtual HRESULT ClearExceptionCallback() = 0; - - //------------------------------------------------ - // IDebugControl2 - //------------------------------------------------ - - // Checks for a user interrupt, such a Ctrl-C - // or stop button. - // This method is reentrant. - virtual HRESULT GetInterrupt( - void) = 0; - - virtual HRESULT OutputVaList( - ULONG mask, - PCSTR format, - va_list args) = 0; - - // Returns information about the debuggee such - // as user vs. kernel, dump vs. live, etc. - virtual HRESULT GetDebuggeeType( - PULONG debugClass, - PULONG qualifier) = 0; - - // Returns the page size for the currently executing - // processor context. The page size may vary between - // processor types. - virtual HRESULT GetPageSize( - PULONG size) = 0; - - // Returns the type of processor used in the - // current processor context. - virtual HRESULT GetExecutingProcessorType( - PULONG type) = 0; - - // Executes the given command string. - // If the string has multiple commands - // Execute will not return until all - // of them have been executed. If this - // requires waiting for the debuggee to - // execute an internal wait will be done - // so Execute can take an arbitrary amount - // of time. - virtual HRESULT Execute( - ULONG outputControl, - PCSTR command, - ULONG flags) = 0; - - // Retrieves information about the last event that occurred. - // EventType is one of the event callback mask bits. - // ExtraInformation contains additional event-specific - // information. Not all events have additional information. - virtual HRESULT GetLastEventInformation( - PULONG type, - PULONG processId, - PULONG threadId, - PVOID extraInformation, - ULONG extraInformationSize, - PULONG extraInformationUsed, - PSTR description, - ULONG descriptionSize, - PULONG descriptionUsed) = 0; - - virtual HRESULT Disassemble( - ULONG64 offset, - ULONG flags, - PSTR buffer, - ULONG bufferSize, - PULONG disassemblySize, - PULONG64 endOffset) = 0; - - //---------------------------------------------------------------------------- - // IDebugControl4 - //---------------------------------------------------------------------------- - - // Stack tracing with a full initial context - // and full context return for each frame. - // The FrameContextsSize parameter is the total - // byte size of FrameContexts. FrameContextsEntrySize - // gives the byte size of each entry in - // FrameContexts. - virtual HRESULT GetContextStackTrace( - PVOID startContext, - ULONG startContextSize, - PDEBUG_STACK_FRAME frames, - ULONG framesSize, - PVOID frameContexts, - ULONG frameContextsSize, - ULONG frameContextsEntrySize, - PULONG framesFilled) = 0; - - //------------------------------------------------ - // IDebugDataSpaces - //------------------------------------------------ - - virtual HRESULT ReadVirtual( - ULONG64 offset, - PVOID buffer, - ULONG bufferSize, - PULONG bytesRead) = 0; - - virtual HRESULT WriteVirtual( - ULONG64 offset, - PVOID buffer, - ULONG bufferSize, - PULONG bytesWritten) = 0; - - //------------------------------------------------ - // IDebugSymbols - //------------------------------------------------ - - // Controls the symbol options used during - // symbol operations. - // Uses the same flags as dbghelps SymSetOptions. - virtual HRESULT GetSymbolOptions( - PULONG options) = 0; - - virtual HRESULT GetNameByOffset( - ULONG64 offset, - PSTR nameBuffer, - ULONG nameBufferSize, - PULONG nameSize, - PULONG64 displacement) = 0; - - // Enumerates the engines list of modules - // loaded for the current process. This may - // or may not match the system module list - // for the process. Reload can be used to - // synchronize the engines list with the system - // if necessary. - // Some sessions also track recently unloaded - // code modules for help in analyzing failures - // where an attempt is made to call unloaded code. - // These modules are indexed after the loaded - // modules. - virtual HRESULT GetNumberModules( - PULONG loaded, - PULONG unloaded) = 0; - - virtual HRESULT GetModuleByIndex( - ULONG index, - PULONG64 base) = 0; - - // The module name may not be unique. - // This method returns the first match. - virtual HRESULT GetModuleByModuleName( - PCSTR name, - ULONG startIndex, - PULONG index, - PULONG64 base) = 0; - - // Offset can be any offset within - // the module extent. Extents may - // not be unique when including unloaded - // drivers. This method returns the - // first match. - virtual HRESULT GetModuleByOffset( - ULONG64 offset, - ULONG startIndex, - PULONG index, - PULONG64 base) = 0; - - // If Index is DEBUG_ANY_ID the base address - // is used to look up the module instead. - virtual HRESULT GetModuleNames( - ULONG index, - ULONG64 base, - PSTR imageNameBuffer, - ULONG imageNameBufferSize, - PULONG imageNameSize, - PSTR moduleNameBuffer, - ULONG moduleNameBufferSize, - PULONG moduleNameSize, - PSTR loadedImageNameBuffer, - ULONG loadedImageNameBufferSize, - PULONG loadedImageNameSize) = 0; - - HRESULT virtual GetLineByOffset( - ULONG64 offset, - PULONG line, - PSTR fileBuffer, - ULONG fileBufferSize, - PULONG fileSize, - PULONG64 displacement) = 0; - - HRESULT virtual GetSourceFileLineOffsets( - PCSTR file, - PULONG64 buffer, - ULONG bufferLines, - PULONG fileLines) = 0; - - // Uses the given file path and the source path - // information to try and locate an existing file. - // The given file path is merged with elements - // of the source path and checked for existence. - // If a match is found the element used is returned. - // A starting element can be specified to restrict - // the search to a subset of the path elements; - // this can be useful when checking for multiple - // matches along the source path. - // The returned element can be 1, indicating - // the file was found directly and not on the path. - HRESULT virtual FindSourceFile( - ULONG startElement, - PCSTR file, - ULONG flags, - PULONG foundElement, - PSTR buffer, - ULONG bufferSize, - PULONG foundSize) = 0; - - //------------------------------------------------ - // IDebugSystemObjects - //------------------------------------------------ - - virtual HRESULT GetCurrentProcessId( - PULONG id) = 0; - - // Controls implicit thread used by the - // debug engine. The debuggers current - // thread is just a piece of data held - // by the debugger for calls which use - // thread-specific information. In those - // calls the debuggers current thread is used. - // The debuggers current thread is not related - // to any system thread attribute. - // IDs for threads are small integer IDs - // maintained by the engine. They are not - // related to system thread IDs. - virtual HRESULT GetCurrentThreadId( - PULONG id) = 0; - - virtual HRESULT SetCurrentThreadId( - ULONG id) = 0; - - // Returns the system unique ID for the current thread. - // Not currently supported when kernel debugging. - virtual HRESULT GetCurrentThreadSystemId( - PULONG sysId) = 0; - - // Looks up a debugger thread ID for the given - // system thread ID. - // Currently when kernel debugging this will fail - // if the thread is not executing on a processor. - virtual HRESULT GetThreadIdBySystemId( - ULONG sysId, - PULONG id) = 0; - - // This is a special sos/lldb function used to implement the ICLRDataTarget interface and - // not actually part of dbgeng's IDebugSystemObjects interface. - virtual HRESULT GetThreadContextById( - /* [in] */ ULONG32 threadID, - /* [in] */ ULONG32 contextFlags, - /* [in] */ ULONG32 contextSize, - /* [out, size_is(contextSize)] */ PBYTE context) = 0; - - //------------------------------------------------ - // IDebugRegister - //------------------------------------------------ - - // This is the combination of dbgeng's GetIndexByName and GetValue and not - // actually part of the dbgeng's IDebugRegister interface. - virtual HRESULT GetValueByName( - PCSTR name, - PDWORD_PTR value) = 0; - - // Abstracted pieces of processor information. - // The mapping of these values to architectural - // registers is architecture-specific and their - // interpretation and existence may vary. They - // are intended to be directly compatible with - // calls which take this information, such as - // stack walking. - virtual HRESULT GetInstructionOffset( - PULONG64 offset) = 0; - - virtual HRESULT GetStackOffset( - PULONG64 offset) = 0; - - virtual HRESULT GetFrameOffset( - PULONG64 offset) = 0; -}; - -#ifdef __cplusplus -}; -#endif - -#endif // #ifndef __LLDBSERVICES_H__ diff --git a/src/ToolBox/SOS/lldbplugin/mstypes.h b/src/ToolBox/SOS/lldbplugin/mstypes.h deleted file mode 100644 index 9b6f261be3..0000000000 --- a/src/ToolBox/SOS/lldbplugin/mstypes.h +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// Contains some definitions duplicated from pal.h, palrt.h, rpc.h, -// etc. because they have various conflicits with the linux standard -// runtime h files like wchar_t, memcpy, etc. - -#include <pal_mstypes.h> - -#define MAX_PATH 260 - -// Platform-specific library naming -// -#ifdef __APPLE__ -#define MAKEDLLNAME_W(name) u"lib" name u".dylib" -#define MAKEDLLNAME_A(name) "lib" name ".dylib" -#elif defined(_AIX) -#define MAKEDLLNAME_W(name) L"lib" name L".a" -#define MAKEDLLNAME_A(name) "lib" name ".a" -#elif defined(__hppa__) || defined(_IA64_) -#define MAKEDLLNAME_W(name) L"lib" name L".sl" -#define MAKEDLLNAME_A(name) "lib" name ".sl" -#else -#define MAKEDLLNAME_W(name) u"lib" name u".so" -#define MAKEDLLNAME_A(name) "lib" name ".so" -#endif diff --git a/src/ToolBox/SOS/lldbplugin/services.cpp b/src/ToolBox/SOS/lldbplugin/services.cpp deleted file mode 100644 index aeca020842..0000000000 --- a/src/ToolBox/SOS/lldbplugin/services.cpp +++ /dev/null @@ -1,1746 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#include <cstdarg> -#include <cstdlib> -#include "sosplugin.h" -#include <string.h> -#include <string> - -#define CONVERT_FROM_SIGN_EXTENDED(offset) ((ULONG_PTR)(offset)) - -ULONG g_currentThreadIndex = (ULONG)-1; -ULONG g_currentThreadSystemId = (ULONG)-1; -char *g_coreclrDirectory; - -LLDBServices::LLDBServices(lldb::SBDebugger &debugger, lldb::SBCommandReturnObject &returnObject, lldb::SBProcess *process, lldb::SBThread *thread) : - m_ref(1), - m_debugger(debugger), - m_returnObject(returnObject), - m_currentProcess(process), - m_currentThread(thread) -{ - returnObject.SetStatus(lldb::eReturnStatusSuccessFinishResult); -} - -LLDBServices::~LLDBServices() -{ -} - -//---------------------------------------------------------------------------- -// IUnknown -//---------------------------------------------------------------------------- - -HRESULT -LLDBServices::QueryInterface( - REFIID InterfaceId, - PVOID* Interface - ) -{ - if (InterfaceId == __uuidof(IUnknown) || - InterfaceId == __uuidof(ILLDBServices)) - { - *Interface = (ILLDBServices*)this; - AddRef(); - return S_OK; - } - else - { - *Interface = NULL; - return E_NOINTERFACE; - } -} - -ULONG -LLDBServices::AddRef() -{ - LONG ref = InterlockedIncrement(&m_ref); - return ref; -} - -ULONG -LLDBServices::Release() -{ - LONG ref = InterlockedDecrement(&m_ref); - if (ref == 0) - { - delete this; - } - return ref; -} - -//---------------------------------------------------------------------------- -// ILLDBServices -//---------------------------------------------------------------------------- - -PCSTR -LLDBServices::GetCoreClrDirectory() -{ - return g_coreclrDirectory; -} - -DWORD_PTR -LLDBServices::GetExpression( - PCSTR exp) -{ - if (exp == nullptr) - { - return 0; - } - - lldb::SBFrame frame = GetCurrentFrame(); - if (!frame.IsValid()) - { - return 0; - } - - DWORD_PTR result = 0; - lldb::SBError error; - std::string str; - - // To be compatible with windbg/dbgeng, we need to emulate the default - // hex radix (because sos prints addresses and other hex values without - // the 0x) by first prepending 0x and if that fails use the actual - // undecorated expression. - str.append("0x"); - str.append(exp); - - result = GetExpression(frame, error, str.c_str()); - if (error.Fail()) - { - result = GetExpression(frame, error, exp); - } - - return result; -} - -// Internal function -DWORD_PTR -LLDBServices::GetExpression( - /* const */ lldb::SBFrame& frame, - lldb::SBError& error, - PCSTR exp) -{ - DWORD_PTR result = 0; - - lldb::SBValue value = frame.EvaluateExpression(exp, lldb::eNoDynamicValues); - if (value.IsValid()) - { - result = value.GetValueAsUnsigned(error); - } - - return result; -} - -// -// lldb doesn't have a way or API to unwind an arbitrary context (IP, SP) -// and return the next frame so we have to stick with the native frames -// lldb has found and find the closest frame to the incoming context SP. -// -HRESULT -LLDBServices::VirtualUnwind( - DWORD threadID, - ULONG32 contextSize, - PBYTE context) -{ - lldb::SBProcess process; - lldb::SBThread thread; - - if (context == NULL || contextSize < sizeof(DT_CONTEXT)) - { - return E_INVALIDARG; - } - - process = GetCurrentProcess(); - if (!process.IsValid()) - { - return E_FAIL; - } - - thread = process.GetThreadByID(threadID); - if (!thread.IsValid()) - { - return E_FAIL; - } - - DT_CONTEXT *dtcontext = (DT_CONTEXT*)context; - lldb::SBFrame frameFound; - -#ifdef DBG_TARGET_AMD64 - DWORD64 spToFind = dtcontext->Rsp; -#elif DBG_TARGET_X86 - DWORD spToFind = dtcontext->Esp; -#elif DBG_TARGET_ARM - DWORD spToFind = dtcontext->Sp; -#elif DBG_TARGET_ARM64 - DWORD64 spToFind = dtcontext->Sp; -#else -#error "spToFind undefined for this platform" -#endif - - int numFrames = thread.GetNumFrames(); - for (int i = 0; i < numFrames; i++) - { - lldb::SBFrame frame = thread.GetFrameAtIndex(i); - if (!frame.IsValid()) - { - break; - } - lldb::addr_t sp = frame.GetSP(); - - if ((i + 1) < numFrames) - { - lldb::SBFrame frameNext = thread.GetFrameAtIndex(i + 1); - if (frameNext.IsValid()) - { - lldb::addr_t spNext = frameNext.GetSP(); - - // An exact match of the current frame's SP would be nice - // but sometimes the incoming context is between lldb frames - if (spToFind >= sp && spToFind < spNext) - { - frameFound = frameNext; - break; - } - } - } - } - - if (!frameFound.IsValid()) - { - return E_FAIL; - } - - GetContextFromFrame(frameFound, dtcontext); - - return S_OK; -} - -bool -ExceptionBreakpointCallback( - void *baton, - lldb::SBProcess &process, - lldb::SBThread &thread, - lldb::SBBreakpointLocation &location) -{ - lldb::SBDebugger debugger = process.GetTarget().GetDebugger(); - - // Send the normal and error output to stdout/stderr since we - // don't have a return object from the command interpreter. - lldb::SBCommandReturnObject result; - result.SetImmediateOutputFile(stdout); - result.SetImmediateErrorFile(stderr); - - // Save the process and thread to be used by the current process/thread - // helper functions. - LLDBServices* client = new LLDBServices(debugger, result, &process, &thread); - return ((PFN_EXCEPTION_CALLBACK)baton)(client) == S_OK; -} - -lldb::SBBreakpoint g_exceptionbp; - -HRESULT -LLDBServices::SetExceptionCallback( - PFN_EXCEPTION_CALLBACK callback) -{ - if (!g_exceptionbp.IsValid()) - { - lldb::SBTarget target = m_debugger.GetSelectedTarget(); - if (!target.IsValid()) - { - return E_FAIL; - } - lldb::SBBreakpoint exceptionbp = target.BreakpointCreateForException(lldb::LanguageType::eLanguageTypeC_plus_plus, false, true); - if (!exceptionbp.IsValid()) - { - return E_FAIL; - } -#ifdef FLAGS_ANONYMOUS_ENUM - exceptionbp.AddName("DoNotDeleteOrDisable"); -#endif - exceptionbp.SetCallback(ExceptionBreakpointCallback, (void *)callback); - g_exceptionbp = exceptionbp; - } - return S_OK; -} - -HRESULT -LLDBServices::ClearExceptionCallback() -{ - if (g_exceptionbp.IsValid()) - { - lldb::SBTarget target = m_debugger.GetSelectedTarget(); - if (!target.IsValid()) - { - return E_FAIL; - } - target.BreakpointDelete(g_exceptionbp.GetID()); - g_exceptionbp = lldb::SBBreakpoint(); - } - return S_OK; -} - -//---------------------------------------------------------------------------- -// IDebugControl2 -//---------------------------------------------------------------------------- - -// Checks for a user interrupt, such a Ctrl-C -// or stop button. -// This method is reentrant. -HRESULT -LLDBServices::GetInterrupt() -{ - return E_FAIL; -} - -// Sends output through clients -// output callbacks if the mask is allowed -// by the current output control mask and -// according to the output distribution -// settings. -HRESULT -LLDBServices::Output( - ULONG mask, - PCSTR format, - ...) -{ - va_list args; - va_start (args, format); - HRESULT result = OutputVaList(mask, format, args); - va_end (args); - return result; -} - -HRESULT -LLDBServices::OutputVaList( - ULONG mask, - PCSTR format, - va_list args) -{ - HRESULT result = S_OK; - char str[1024]; - - va_list args_copy; - va_copy (args_copy, args); - - // Try and format our string into a fixed buffer first and see if it fits - size_t length = ::vsnprintf(str, sizeof(str), format, args); - if (length < sizeof(str)) - { - OutputString(mask, str); - } - else - { - // Our stack buffer wasn't big enough to contain the entire formatted - // string, so lets let vasprintf create the string for us! - char *str_ptr = nullptr; - length = ::vasprintf(&str_ptr, format, args_copy); - if (str_ptr) - { - OutputString(mask, str_ptr); - ::free (str_ptr); - } - else - { - result = E_FAIL; - } - } - - va_end (args_copy); - - return result; -} - -// The following methods allow direct control -// over the distribution of the given output -// for situations where something other than -// the default is desired. These methods require -// extra work in the engine so they should -// only be used when necessary. -HRESULT -LLDBServices::ControlledOutput( - ULONG outputControl, - ULONG mask, - PCSTR format, - ...) -{ - va_list args; - va_start (args, format); - HRESULT result = ControlledOutputVaList(outputControl, mask, format, args); - va_end (args); - return result; -} - -HRESULT -LLDBServices::ControlledOutputVaList( - ULONG outputControl, - ULONG mask, - PCSTR format, - va_list args) -{ - return OutputVaList(mask, format, args); -} - -// Returns information about the debuggee such -// as user vs. kernel, dump vs. live, etc. -HRESULT -LLDBServices::GetDebuggeeType( - PULONG debugClass, - PULONG qualifier) -{ - *debugClass = DEBUG_CLASS_USER_WINDOWS; - *qualifier = 0; - return S_OK; -} - -// Returns the page size for the currently executing -// processor context. The page size may vary between -// processor types. -HRESULT -LLDBServices::GetPageSize( - PULONG size) -{ - *size = 4096; - return S_OK; -} - -HRESULT -LLDBServices::GetExecutingProcessorType( - PULONG type) -{ -#ifdef DBG_TARGET_AMD64 - *type = IMAGE_FILE_MACHINE_AMD64; -#elif DBG_TARGET_ARM - *type = IMAGE_FILE_MACHINE_ARMNT; -#elif DBG_TARGET_ARM64 - *type = IMAGE_FILE_MACHINE_ARM64; -#elif DBG_TARGET_X86 - *type = IMAGE_FILE_MACHINE_I386; -#else -#error "Unsupported target" -#endif - return S_OK; -} - -HRESULT -LLDBServices::Execute( - ULONG outputControl, - PCSTR command, - ULONG flags) -{ - lldb::SBCommandInterpreter interpreter = m_debugger.GetCommandInterpreter(); - - lldb::SBCommandReturnObject result; - lldb::ReturnStatus status = interpreter.HandleCommand(command, result); - - return status <= lldb::eReturnStatusSuccessContinuingResult ? S_OK : E_FAIL; -} - -// PAL raise exception function and exception record pointer variable name -// See coreclr\src\pal\src\exception\seh-unwind.cpp for the details. This -// function depends on RtlpRaisException not being inlined or optimized. -#define FUNCTION_NAME "RtlpRaiseException" -#define VARIABLE_NAME "ExceptionRecord" - -HRESULT -LLDBServices::GetLastEventInformation( - PULONG type, - PULONG processId, - PULONG threadId, - PVOID extraInformation, - ULONG extraInformationSize, - PULONG extraInformationUsed, - PSTR description, - ULONG descriptionSize, - PULONG descriptionUsed) -{ - if (extraInformationSize < sizeof(DEBUG_LAST_EVENT_INFO_EXCEPTION) || - type == NULL || processId == NULL || threadId == NULL || extraInformationUsed == NULL) - { - return E_INVALIDARG; - } - - *type = DEBUG_EVENT_EXCEPTION; - *processId = 0; - *threadId = 0; - *extraInformationUsed = sizeof(DEBUG_LAST_EVENT_INFO_EXCEPTION); - - DEBUG_LAST_EVENT_INFO_EXCEPTION *pdle = (DEBUG_LAST_EVENT_INFO_EXCEPTION *)extraInformation; - pdle->FirstChance = 1; - - lldb::SBProcess process = GetCurrentProcess(); - if (!process.IsValid()) - { - return E_FAIL; - } - lldb::SBThread thread = GetCurrentThread(); - if (!thread.IsValid()) - { - return E_FAIL; - } - - *processId = process.GetProcessID(); - *threadId = thread.GetThreadID(); - - // Enumerate each stack frame at the special "throw" - // breakpoint and find the raise exception function - // with the exception record parameter. - int numFrames = thread.GetNumFrames(); - for (int i = 0; i < numFrames; i++) - { - lldb::SBFrame frame = thread.GetFrameAtIndex(i); - if (!frame.IsValid()) - { - break; - } - - const char *functionName = frame.GetFunctionName(); - if (functionName == NULL || strncmp(functionName, FUNCTION_NAME, sizeof(FUNCTION_NAME) - 1) != 0) - { - continue; - } - - lldb::SBValue exValue = frame.FindVariable(VARIABLE_NAME); - if (!exValue.IsValid()) - { - break; - } - - lldb::SBError error; - ULONG64 pExceptionRecord = exValue.GetValueAsUnsigned(error); - if (error.Fail()) - { - break; - } - - process.ReadMemory(pExceptionRecord, &pdle->ExceptionRecord, sizeof(pdle->ExceptionRecord), error); - if (error.Fail()) - { - break; - } - - return S_OK; - } - - return E_FAIL; -} - -HRESULT -LLDBServices::Disassemble( - ULONG64 offset, - ULONG flags, - PSTR buffer, - ULONG bufferSize, - PULONG disassemblySize, - PULONG64 endOffset) -{ - lldb::SBInstruction instruction; - lldb::SBInstructionList list; - lldb::SBTarget target; - lldb::SBAddress address; - lldb::SBError error; - lldb::SBData data; - std::string str; - HRESULT hr = S_OK; - ULONG size = 0; - uint8_t byte; - int cch; - - // lldb doesn't expect sign-extended address - offset = CONVERT_FROM_SIGN_EXTENDED(offset); - - if (buffer == NULL) - { - hr = E_INVALIDARG; - goto exit; - } - *buffer = 0; - - target = m_debugger.GetSelectedTarget(); - if (!target.IsValid()) - { - hr = E_INVALIDARG; - goto exit; - } - address = target.ResolveLoadAddress(offset); - if (!address.IsValid()) - { - hr = E_INVALIDARG; - goto exit; - } - list = target.ReadInstructions(address, 1, "intel"); - if (!list.IsValid()) - { - hr = E_FAIL; - goto exit; - } - instruction = list.GetInstructionAtIndex(0); - if (!instruction.IsValid()) - { - hr = E_FAIL; - goto exit; - } - cch = snprintf(buffer, bufferSize, "%016llx ", (unsigned long long)offset); - buffer += cch; - bufferSize -= cch; - - size = instruction.GetByteSize(); - data = instruction.GetData(target); - for (ULONG i = 0; i < size && bufferSize > 0; i++) - { - byte = data.GetUnsignedInt8(error, i); - if (error.Fail()) - { - hr = E_FAIL; - goto exit; - } - cch = snprintf(buffer, bufferSize, "%02x", byte); - buffer += cch; - bufferSize -= cch; - } - // Pad the data bytes to 16 chars - cch = size * 2; - while (bufferSize > 0) - { - *buffer++ = ' '; - bufferSize--; - if (++cch >= 21) - break; - } - - cch = snprintf(buffer, bufferSize, "%s", instruction.GetMnemonic(target)); - buffer += cch; - bufferSize -= cch; - - // Pad the mnemonic to 8 chars - while (bufferSize > 0) - { - *buffer++ = ' '; - bufferSize--; - if (++cch >= 8) - break; - } - snprintf(buffer, bufferSize, "%s\n", instruction.GetOperands(target)); - -exit: - if (disassemblySize != NULL) - { - *disassemblySize = size; - } - if (endOffset != NULL) - { - *endOffset = offset + size; - } - return hr; -} - -// Internal output string function -void -LLDBServices::OutputString( - ULONG mask, - PCSTR str) -{ - if (mask == DEBUG_OUTPUT_ERROR) - { - m_returnObject.SetStatus(lldb::eReturnStatusFailed); - } - // Can not use AppendMessage or AppendWarning because they add a newline. SetError - // can not be used for DEBUG_OUTPUT_ERROR mask because it caches the error strings - // seperately from the normal output so error/normal texts are not intermixed - // correctly. - m_returnObject.Printf("%s", str); -} - -//---------------------------------------------------------------------------- -// IDebugControl4 -//---------------------------------------------------------------------------- - -HRESULT -LLDBServices::GetContextStackTrace( - PVOID startContext, - ULONG startContextSize, - PDEBUG_STACK_FRAME frames, - ULONG framesSize, - PVOID frameContexts, - ULONG frameContextsSize, - ULONG frameContextsEntrySize, - PULONG framesFilled) -{ - DT_CONTEXT *currentContext = (DT_CONTEXT*)frameContexts; - PDEBUG_STACK_FRAME currentFrame = frames; - lldb::SBThread thread; - lldb::SBFrame frame; - ULONG cFrames = 0; - HRESULT hr = S_OK; - - // Doesn't support a starting context - if (startContext != NULL || frames == NULL || frameContexts == NULL || frameContextsEntrySize != sizeof(DT_CONTEXT)) - { - hr = E_INVALIDARG; - goto exit; - } - - thread = GetCurrentThread(); - if (!thread.IsValid()) - { - hr = E_FAIL; - goto exit; - } - - frame = thread.GetFrameAtIndex(0); - for (uint32_t i = 0; i < thread.GetNumFrames(); i++) - { - if (!frame.IsValid() || (cFrames > framesSize) || ((char *)currentContext > ((char *)frameContexts + frameContextsSize))) - { - break; - } - lldb::SBFrame framePrevious; - lldb::SBFrame frameNext; - - currentFrame->InstructionOffset = frame.GetPC(); - currentFrame->StackOffset = frame.GetSP(); - - currentFrame->FuncTableEntry = 0; - currentFrame->Params[0] = 0; - currentFrame->Params[1] = 0; - currentFrame->Params[2] = 0; - currentFrame->Params[3] = 0; - currentFrame->Virtual = i == 0 ? TRUE : FALSE; - currentFrame->FrameNumber = frame.GetFrameID(); - - frameNext = thread.GetFrameAtIndex(i + 1); - if (frameNext.IsValid()) - { - currentFrame->ReturnOffset = frameNext.GetPC(); - } - - if (framePrevious.IsValid()) - { - currentFrame->FrameOffset = framePrevious.GetSP(); - } - else - { - currentFrame->FrameOffset = frame.GetSP(); - } - - GetContextFromFrame(frame, currentContext); - - framePrevious = frame; - frame = frameNext; - currentContext++; - currentFrame++; - cFrames++; - } - -exit: - if (framesFilled != NULL) - { - *framesFilled = cFrames; - } - return hr; -} - -//---------------------------------------------------------------------------- -// IDebugDataSpaces -//---------------------------------------------------------------------------- - -HRESULT -LLDBServices::ReadVirtual( - ULONG64 offset, - PVOID buffer, - ULONG bufferSize, - PULONG bytesRead) -{ - lldb::SBError error; - size_t read = 0; - - // lldb doesn't expect sign-extended address - offset = CONVERT_FROM_SIGN_EXTENDED(offset); - - lldb::SBProcess process = GetCurrentProcess(); - if (!process.IsValid()) - { - goto exit; - } - - read = process.ReadMemory(offset, buffer, bufferSize, error); - -exit: - if (bytesRead) - { - *bytesRead = read; - } - return error.Success() || (read != 0) ? S_OK : E_FAIL; -} - -HRESULT -LLDBServices::WriteVirtual( - ULONG64 offset, - PVOID buffer, - ULONG bufferSize, - PULONG bytesWritten) -{ - lldb::SBError error; - size_t written = 0; - - // lldb doesn't expect sign-extended address - offset = CONVERT_FROM_SIGN_EXTENDED(offset); - - lldb::SBProcess process = GetCurrentProcess(); - if (!process.IsValid()) - { - goto exit; - } - - written = process.WriteMemory(offset, buffer, bufferSize, error); - -exit: - if (bytesWritten) - { - *bytesWritten = written; - } - return error.Success() || (written != 0) ? S_OK : E_FAIL; -} - -//---------------------------------------------------------------------------- -// IDebugSymbols -//---------------------------------------------------------------------------- - -HRESULT -LLDBServices::GetSymbolOptions( - PULONG options) -{ - *options = SYMOPT_LOAD_LINES; - return S_OK; -} - -HRESULT -LLDBServices::GetNameByOffset( - ULONG64 offset, - PSTR nameBuffer, - ULONG nameBufferSize, - PULONG nameSize, - PULONG64 displacement) -{ - ULONG64 disp = DEBUG_INVALID_OFFSET; - HRESULT hr = S_OK; - - lldb::SBTarget target; - lldb::SBAddress address; - lldb::SBModule module; - lldb::SBFileSpec file; - lldb::SBSymbol symbol; - std::string str; - - // lldb doesn't expect sign-extended address - offset = CONVERT_FROM_SIGN_EXTENDED(offset); - - target = m_debugger.GetSelectedTarget(); - if (!target.IsValid()) - { - hr = E_FAIL; - goto exit; - } - - address = target.ResolveLoadAddress(offset); - if (!address.IsValid()) - { - hr = E_INVALIDARG; - goto exit; - } - - module = address.GetModule(); - if (!module.IsValid()) - { - hr = E_FAIL; - goto exit; - } - - file = module.GetFileSpec(); - if (file.IsValid()) - { - str.append(file.GetFilename()); - } - - symbol = address.GetSymbol(); - if (symbol.IsValid()) - { - lldb::SBAddress startAddress = symbol.GetStartAddress(); - disp = address.GetOffset() - startAddress.GetOffset(); - - const char *name = symbol.GetName(); - if (name) - { - if (file.IsValid()) - { - str.append("!"); - } - str.append(name); - } - } - - str.append(1, '\0'); - -exit: - if (nameSize) - { - *nameSize = str.length(); - } - if (nameBuffer) - { - str.copy(nameBuffer, nameBufferSize); - } - if (displacement) - { - *displacement = disp; - } - return hr; -} - -HRESULT -LLDBServices::GetNumberModules( - PULONG loaded, - PULONG unloaded) -{ - ULONG numModules = 0; - HRESULT hr = S_OK; - - lldb::SBTarget target = m_debugger.GetSelectedTarget(); - if (!target.IsValid()) - { - hr = E_FAIL; - goto exit; - } - - numModules = target.GetNumModules(); - -exit: - if (loaded) - { - *loaded = numModules; - } - if (unloaded) - { - *unloaded = 0; - } - return hr; -} - -HRESULT LLDBServices::GetModuleByIndex( - ULONG index, - PULONG64 base) -{ - ULONG64 moduleBase = UINT64_MAX; - - lldb::SBTarget target; - lldb::SBModule module; - - target = m_debugger.GetSelectedTarget(); - if (!target.IsValid()) - { - goto exit; - } - - module = target.GetModuleAtIndex(index); - if (!module.IsValid()) - { - goto exit; - } - - moduleBase = GetModuleBase(target, module); - -exit: - if (base) - { - *base = moduleBase; - } - return moduleBase == UINT64_MAX ? E_FAIL : S_OK; -} - -HRESULT -LLDBServices::GetModuleByModuleName( - PCSTR name, - ULONG startIndex, - PULONG index, - PULONG64 base) -{ - ULONG64 moduleBase = UINT64_MAX; - ULONG moduleIndex = UINT32_MAX; - - lldb::SBTarget target; - lldb::SBModule module; - lldb::SBFileSpec fileSpec; - fileSpec.SetFilename(name); - - target = m_debugger.GetSelectedTarget(); - if (!target.IsValid()) - { - goto exit; - } - - module = target.FindModule(fileSpec); - if (!module.IsValid()) - { - goto exit; - } - - moduleBase = GetModuleBase(target, module); - - if (index) - { - int numModules = target.GetNumModules(); - for (int mi = startIndex; mi < numModules; mi++) - { - lldb::SBModule mod = target.GetModuleAtIndex(mi); - if (module == mod) - { - moduleIndex = mi; - break; - } - } - } - -exit: - if (index) - { - *index = moduleIndex; - } - if (base) - { - *base = moduleBase; - } - return moduleBase == UINT64_MAX ? E_FAIL : S_OK; -} - -HRESULT -LLDBServices::GetModuleByOffset( - ULONG64 offset, - ULONG startIndex, - PULONG index, - PULONG64 base) -{ - ULONG64 moduleBase = UINT64_MAX; - ULONG moduleIndex = UINT32_MAX; - - lldb::SBTarget target; - int numModules; - - // lldb doesn't expect sign-extended address - offset = CONVERT_FROM_SIGN_EXTENDED(offset); - - target = m_debugger.GetSelectedTarget(); - if (!target.IsValid()) - { - goto exit; - } - - numModules = target.GetNumModules(); - for (int mi = startIndex; mi < numModules; mi++) - { - lldb::SBModule module = target.GetModuleAtIndex(mi); - - int numSections = module.GetNumSections(); - for (int si = 0; si < numSections; si++) - { - lldb::SBSection section = module.GetSectionAtIndex(si); - if (section.IsValid()) - { - lldb::addr_t baseAddress = section.GetLoadAddress(target); - if (baseAddress != LLDB_INVALID_ADDRESS) - { - if (offset > baseAddress) - { - if ((offset - baseAddress) < section.GetByteSize()) - { - moduleIndex = mi; - moduleBase = baseAddress - section.GetFileOffset(); - goto exit; - } - } - } - } - } - } - -exit: - if (index) - { - *index = moduleIndex; - } - if (base) - { - *base = moduleBase; - } - return moduleBase == UINT64_MAX ? E_FAIL : S_OK; -} - -HRESULT -LLDBServices::GetModuleNames( - ULONG index, - ULONG64 base, - PSTR imageNameBuffer, - ULONG imageNameBufferSize, - PULONG imageNameSize, - PSTR moduleNameBuffer, - ULONG moduleNameBufferSize, - PULONG moduleNameSize, - PSTR loadedImageNameBuffer, - ULONG loadedImageNameBufferSize, - PULONG loadedImageNameSize) -{ - lldb::SBTarget target; - lldb::SBFileSpec fileSpec; - HRESULT hr = S_OK; - - // lldb doesn't expect sign-extended address - base = CONVERT_FROM_SIGN_EXTENDED(base); - - target = m_debugger.GetSelectedTarget(); - if (!target.IsValid()) - { - hr = E_FAIL; - goto exit; - } - - if (index != DEBUG_ANY_ID) - { - lldb::SBModule module = target.GetModuleAtIndex(index); - if (module.IsValid()) - { - fileSpec = module.GetFileSpec(); - } - } - else - { - int numModules = target.GetNumModules(); - for (int mi = 0; mi < numModules; mi++) - { - lldb::SBModule module = target.GetModuleAtIndex(mi); - if (module.IsValid()) - { - ULONG64 moduleBase = GetModuleBase(target, module); - if (base == moduleBase) - { - fileSpec = module.GetFileSpec(); - break; - } - } - } - } - - if (!fileSpec.IsValid()) - { - hr = E_FAIL; - goto exit; - } - -exit: - if (imageNameBuffer) - { - int size = fileSpec.GetPath(imageNameBuffer, imageNameBufferSize); - if (imageNameSize) - { - *imageNameSize = size; - } - } - if (moduleNameBuffer) - { - const char *fileName = fileSpec.GetFilename(); - if (fileName == NULL) - { - fileName = ""; - } - stpncpy(moduleNameBuffer, fileName, moduleNameBufferSize); - if (moduleNameSize) - { - *moduleNameSize = strlen(fileName); - } - } - if (loadedImageNameBuffer) - { - int size = fileSpec.GetPath(loadedImageNameBuffer, loadedImageNameBufferSize); - if (loadedImageNameSize) - { - *loadedImageNameSize = size; - } - } - return hr; -} - -HRESULT -LLDBServices::GetLineByOffset( - ULONG64 offset, - PULONG fileLine, - PSTR fileBuffer, - ULONG fileBufferSize, - PULONG fileSize, - PULONG64 displacement) -{ - ULONG64 disp = DEBUG_INVALID_OFFSET; - HRESULT hr = S_OK; - ULONG line = 0; - - lldb::SBTarget target; - lldb::SBAddress address; - lldb::SBFileSpec file; - lldb::SBLineEntry lineEntry; - std::string str; - - // lldb doesn't expect sign-extended address - offset = CONVERT_FROM_SIGN_EXTENDED(offset); - - target = m_debugger.GetSelectedTarget(); - if (!target.IsValid()) - { - hr = E_FAIL; - goto exit; - } - - address = target.ResolveLoadAddress(offset); - if (!address.IsValid()) - { - hr = E_INVALIDARG; - goto exit; - } - - if (displacement) - { - lldb::SBSymbol symbol = address.GetSymbol(); - if (symbol.IsValid()) - { - lldb::SBAddress startAddress = symbol.GetStartAddress(); - disp = address.GetOffset() - startAddress.GetOffset(); - } - } - - lineEntry = address.GetLineEntry(); - if (!lineEntry.IsValid()) - { - hr = E_FAIL; - goto exit; - } - - line = lineEntry.GetLine(); - file = lineEntry.GetFileSpec(); - if (file.IsValid()) - { - str.append(file.GetDirectory()); - str.append(1, '/'); - str.append(file.GetFilename()); - } - - str.append(1, '\0'); - -exit: - if (fileLine) - { - *fileLine = line; - } - if (fileSize) - { - *fileSize = str.length(); - } - if (fileBuffer) - { - str.copy(fileBuffer, fileBufferSize); - } - if (displacement) - { - *displacement = disp; - } - return hr; -} - -HRESULT -LLDBServices::GetSourceFileLineOffsets( - PCSTR file, - PULONG64 buffer, - ULONG bufferLines, - PULONG fileLines) -{ - if (fileLines != NULL) - { - *fileLines = (ULONG)-1; - } - return E_NOTIMPL; -} - -HRESULT -LLDBServices::FindSourceFile( - ULONG startElement, - PCSTR file, - ULONG flags, - PULONG foundElement, - PSTR buffer, - ULONG bufferSize, - PULONG foundSize) -{ - return E_NOTIMPL; -} - -// Internal functions -PCSTR -LLDBServices::GetModuleDirectory( - PCSTR name) -{ - lldb::SBTarget target = m_debugger.GetSelectedTarget(); - if (!target.IsValid()) - { - return NULL; - } - - lldb::SBFileSpec fileSpec; - fileSpec.SetFilename(name); - - lldb::SBModule module = target.FindModule(fileSpec); - if (!module.IsValid()) - { - return NULL; - } - - return module.GetFileSpec().GetDirectory(); -} - -ULONG64 -LLDBServices::GetModuleBase( - /* const */ lldb::SBTarget& target, - /* const */ lldb::SBModule& module) -{ - // Find the first section with an valid base address - int numSections = module.GetNumSections(); - for (int si = 0; si < numSections; si++) - { - lldb::SBSection section = module.GetSectionAtIndex(si); - if (section.IsValid()) - { - lldb::addr_t baseAddress = section.GetLoadAddress(target); - if (baseAddress != LLDB_INVALID_ADDRESS) - { - return baseAddress - section.GetFileOffset(); - } - } - } - - return UINT64_MAX; -} - -//---------------------------------------------------------------------------- -// IDebugSystemObjects -//---------------------------------------------------------------------------- - -HRESULT -LLDBServices::GetCurrentProcessId( - PULONG id) -{ - if (id == NULL) - { - return E_INVALIDARG; - } - - lldb::SBProcess process = GetCurrentProcess(); - if (!process.IsValid()) - { - *id = 0; - return E_FAIL; - } - - *id = process.GetProcessID(); - return S_OK; -} - -HRESULT -LLDBServices::GetCurrentThreadId( - PULONG id) -{ - if (id == NULL) - { - return E_INVALIDARG; - } - - lldb::SBThread thread = GetCurrentThread(); - if (!thread.IsValid()) - { - *id = 0; - return E_FAIL; - } - - // This is allow the a valid current TID to be returned to - // workaround a bug in lldb on core dumps. - if (g_currentThreadIndex != (ULONG)-1) - { - *id = g_currentThreadIndex; - return S_OK; - } - - *id = thread.GetIndexID(); - return S_OK; -} - -HRESULT -LLDBServices::SetCurrentThreadId( - ULONG id) -{ - lldb::SBProcess process = GetCurrentProcess(); - if (!process.IsValid()) - { - return E_FAIL; - } - - if (!process.SetSelectedThreadByIndexID(id)) - { - return E_FAIL; - } - - return S_OK; -} - -HRESULT -LLDBServices::GetCurrentThreadSystemId( - PULONG sysId) -{ - if (sysId == NULL) - { - return E_INVALIDARG; - } - - lldb::SBThread thread = GetCurrentThread(); - if (!thread.IsValid()) - { - *sysId = 0; - return E_FAIL; - } - - // This is allow the a valid current TID to be returned to - // workaround a bug in lldb on core dumps. - if (g_currentThreadSystemId != (ULONG)-1) - { - *sysId = g_currentThreadSystemId; - return S_OK; - } - - *sysId = thread.GetThreadID(); - return S_OK; -} - -HRESULT -LLDBServices::GetThreadIdBySystemId( - ULONG sysId, - PULONG threadId) -{ - HRESULT hr = E_FAIL; - ULONG id = 0; - - lldb::SBProcess process; - lldb::SBThread thread; - - if (threadId == NULL) - { - return E_INVALIDARG; - } - - process = GetCurrentProcess(); - if (!process.IsValid()) - { - goto exit; - } - - // If we have a "fake" thread OS (system) id and a fake thread index, - // we need to return fake thread index. - if (g_currentThreadSystemId == sysId && g_currentThreadIndex != (ULONG)-1) - { - id = g_currentThreadIndex; - } - else - { - thread = process.GetThreadByID(sysId); - if (!thread.IsValid()) - { - goto exit; - } - - id = thread.GetIndexID(); - } - hr = S_OK; - -exit: - *threadId = id; - return hr; -} - -HRESULT -LLDBServices::GetThreadContextById( - /* in */ ULONG32 threadID, - /* in */ ULONG32 contextFlags, - /* in */ ULONG32 contextSize, - /* out */ PBYTE context) -{ - lldb::SBProcess process; - lldb::SBThread thread; - lldb::SBFrame frame; - DT_CONTEXT *dtcontext; - HRESULT hr = E_FAIL; - - if (context == NULL || contextSize < sizeof(DT_CONTEXT)) - { - goto exit; - } - memset(context, 0, contextSize); - - process = GetCurrentProcess(); - if (!process.IsValid()) - { - goto exit; - } - - // If we have a "fake" thread OS (system) id and a fake thread index, - // use the fake thread index to get the context. - if (g_currentThreadSystemId == threadID && g_currentThreadIndex != (ULONG)-1) - { - thread = process.GetThreadByIndexID(g_currentThreadIndex); - } - else - { - thread = process.GetThreadByID(threadID); - } - - if (!thread.IsValid()) - { - goto exit; - } - - frame = thread.GetFrameAtIndex(0); - if (!frame.IsValid()) - { - goto exit; - } - - dtcontext = (DT_CONTEXT*)context; - dtcontext->ContextFlags = contextFlags; - - GetContextFromFrame(frame, dtcontext); - hr = S_OK; - -exit: - return hr; -} - -// Internal function -void -LLDBServices::GetContextFromFrame( - /* const */ lldb::SBFrame& frame, - DT_CONTEXT *dtcontext) -{ -#ifdef DBG_TARGET_AMD64 - dtcontext->Rip = frame.GetPC(); - dtcontext->Rsp = frame.GetSP(); - dtcontext->Rbp = frame.GetFP(); - dtcontext->EFlags = GetRegister(frame, "rflags"); - - dtcontext->Rax = GetRegister(frame, "rax"); - dtcontext->Rbx = GetRegister(frame, "rbx"); - dtcontext->Rcx = GetRegister(frame, "rcx"); - dtcontext->Rdx = GetRegister(frame, "rdx"); - dtcontext->Rsi = GetRegister(frame, "rsi"); - dtcontext->Rdi = GetRegister(frame, "rdi"); - dtcontext->R8 = GetRegister(frame, "r8"); - dtcontext->R9 = GetRegister(frame, "r9"); - dtcontext->R10 = GetRegister(frame, "r10"); - dtcontext->R11 = GetRegister(frame, "r11"); - dtcontext->R12 = GetRegister(frame, "r12"); - dtcontext->R13 = GetRegister(frame, "r13"); - dtcontext->R14 = GetRegister(frame, "r14"); - dtcontext->R15 = GetRegister(frame, "r15"); - - dtcontext->SegCs = GetRegister(frame, "cs"); - dtcontext->SegSs = GetRegister(frame, "ss"); - dtcontext->SegDs = GetRegister(frame, "ds"); - dtcontext->SegEs = GetRegister(frame, "es"); - dtcontext->SegFs = GetRegister(frame, "fs"); - dtcontext->SegGs = GetRegister(frame, "gs"); -#elif DBG_TARGET_ARM - dtcontext->Pc = frame.GetPC(); - dtcontext->Sp = frame.GetSP(); - dtcontext->Lr = GetRegister(frame, "lr"); - dtcontext->Cpsr = GetRegister(frame, "cpsr"); - - dtcontext->R0 = GetRegister(frame, "r0"); - dtcontext->R1 = GetRegister(frame, "r1"); - dtcontext->R2 = GetRegister(frame, "r2"); - dtcontext->R3 = GetRegister(frame, "r3"); - dtcontext->R4 = GetRegister(frame, "r4"); - dtcontext->R5 = GetRegister(frame, "r5"); - dtcontext->R6 = GetRegister(frame, "r6"); - dtcontext->R7 = GetRegister(frame, "r7"); - dtcontext->R8 = GetRegister(frame, "r8"); - dtcontext->R9 = GetRegister(frame, "r9"); - dtcontext->R10 = GetRegister(frame, "r10"); - dtcontext->R11 = GetRegister(frame, "r11"); - dtcontext->R12 = GetRegister(frame, "r12"); -#elif DBG_TARGET_X86 - dtcontext->Eip = frame.GetPC(); - dtcontext->Esp = frame.GetSP(); - dtcontext->Ebp = frame.GetFP(); - dtcontext->EFlags = GetRegister(frame, "eflags"); - - dtcontext->Edi = GetRegister(frame, "edi"); - dtcontext->Esi = GetRegister(frame, "esi"); - dtcontext->Ebx = GetRegister(frame, "ebx"); - dtcontext->Edx = GetRegister(frame, "edx"); - dtcontext->Ecx = GetRegister(frame, "ecx"); - dtcontext->Eax = GetRegister(frame, "eax"); - - dtcontext->SegCs = GetRegister(frame, "cs"); - dtcontext->SegSs = GetRegister(frame, "ss"); - dtcontext->SegDs = GetRegister(frame, "ds"); - dtcontext->SegEs = GetRegister(frame, "es"); - dtcontext->SegFs = GetRegister(frame, "fs"); - dtcontext->SegGs = GetRegister(frame, "gs"); -#endif -} - -// Internal function -DWORD_PTR -LLDBServices::GetRegister( - /* const */ lldb::SBFrame& frame, - const char *name) -{ - lldb::SBValue regValue = frame.FindRegister(name); - - lldb::SBError error; - DWORD_PTR result = regValue.GetValueAsUnsigned(error); - - return result; -} - -//---------------------------------------------------------------------------- -// IDebugRegisters -//---------------------------------------------------------------------------- - -HRESULT -LLDBServices::GetValueByName( - PCSTR name, - PDWORD_PTR debugValue) -{ - lldb::SBFrame frame = GetCurrentFrame(); - if (!frame.IsValid()) - { - *debugValue = 0; - return E_FAIL; - } - - lldb::SBValue value = frame.FindRegister(name); - if (!value.IsValid()) - { - *debugValue = 0; - return E_FAIL; - } - - *debugValue = value.GetValueAsUnsigned(); - return S_OK; -} - -HRESULT -LLDBServices::GetInstructionOffset( - PULONG64 offset) -{ - lldb::SBFrame frame = GetCurrentFrame(); - if (!frame.IsValid()) - { - *offset = 0; - return E_FAIL; - } - - *offset = frame.GetPC(); - return S_OK; -} - -HRESULT -LLDBServices::GetStackOffset( - PULONG64 offset) -{ - lldb::SBFrame frame = GetCurrentFrame(); - if (!frame.IsValid()) - { - *offset = 0; - return E_FAIL; - } - - *offset = frame.GetSP(); - return S_OK; -} - -HRESULT -LLDBServices::GetFrameOffset( - PULONG64 offset) -{ - lldb::SBFrame frame = GetCurrentFrame(); - if (!frame.IsValid()) - { - *offset = 0; - return E_FAIL; - } - - *offset = frame.GetFP(); - return S_OK; -} - -//---------------------------------------------------------------------------- -// Helper functions -//---------------------------------------------------------------------------- - -lldb::SBProcess -LLDBServices::GetCurrentProcess() -{ - lldb::SBProcess process; - - if (m_currentProcess == nullptr) - { - lldb::SBTarget target = m_debugger.GetSelectedTarget(); - if (target.IsValid()) - { - process = target.GetProcess(); - } - } - else - { - process = *m_currentProcess; - } - - return process; -} - -lldb::SBThread -LLDBServices::GetCurrentThread() -{ - lldb::SBThread thread; - - if (m_currentThread == nullptr) - { - lldb::SBProcess process = GetCurrentProcess(); - if (process.IsValid()) - { - thread = process.GetSelectedThread(); - } - } - else - { - thread = *m_currentThread; - } - - return thread; -} - -lldb::SBFrame -LLDBServices::GetCurrentFrame() -{ - lldb::SBFrame frame; - - lldb::SBThread thread = GetCurrentThread(); - if (thread.IsValid()) - { - frame = thread.GetSelectedFrame(); - } - - return frame; -} diff --git a/src/ToolBox/SOS/lldbplugin/services.h b/src/ToolBox/SOS/lldbplugin/services.h deleted file mode 100644 index a8fb32f89f..0000000000 --- a/src/ToolBox/SOS/lldbplugin/services.h +++ /dev/null @@ -1,274 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#include <cstdarg> - -class LLDBServices : public ILLDBServices -{ -private: - LONG m_ref; - lldb::SBDebugger &m_debugger; - lldb::SBCommandReturnObject &m_returnObject; - - lldb::SBProcess *m_currentProcess; - lldb::SBThread *m_currentThread; - - void OutputString(ULONG mask, PCSTR str); - ULONG64 GetModuleBase(lldb::SBTarget& target, lldb::SBModule& module); - DWORD_PTR GetExpression(lldb::SBFrame& frame, lldb::SBError& error, PCSTR exp); - void GetContextFromFrame(lldb::SBFrame& frame, DT_CONTEXT *dtcontext); - DWORD_PTR GetRegister(lldb::SBFrame& frame, const char *name); - - lldb::SBProcess GetCurrentProcess(); - lldb::SBThread GetCurrentThread(); - lldb::SBFrame GetCurrentFrame(); - -public: - LLDBServices(lldb::SBDebugger &debugger, lldb::SBCommandReturnObject &returnObject, lldb::SBProcess *process = nullptr, lldb::SBThread *thread = nullptr); - virtual ~LLDBServices(); - - //---------------------------------------------------------------------------- - // IUnknown - //---------------------------------------------------------------------------- - - HRESULT STDMETHODCALLTYPE QueryInterface( - REFIID InterfaceId, - PVOID* Interface); - - ULONG STDMETHODCALLTYPE AddRef(); - - ULONG STDMETHODCALLTYPE Release(); - - //---------------------------------------------------------------------------- - // ILLDBServices - //---------------------------------------------------------------------------- - - PCSTR GetCoreClrDirectory(); - - DWORD_PTR GetExpression( - PCSTR exp); - - HRESULT VirtualUnwind( - DWORD threadID, - ULONG32 contextSize, - PBYTE context); - - HRESULT SetExceptionCallback( - PFN_EXCEPTION_CALLBACK callback); - - HRESULT ClearExceptionCallback(); - - //---------------------------------------------------------------------------- - // IDebugControl2 - //---------------------------------------------------------------------------- - - HRESULT GetInterrupt(); - - HRESULT Output( - ULONG mask, - PCSTR format, - ...); - - HRESULT OutputVaList( - ULONG mask, - PCSTR format, - va_list args); - - HRESULT ControlledOutput( - ULONG outputControl, - ULONG mask, - PCSTR format, - ...); - - HRESULT ControlledOutputVaList( - ULONG outputControl, - ULONG mask, - PCSTR format, - va_list args); - - HRESULT GetDebuggeeType( - PULONG debugClass, - PULONG qualifier); - - HRESULT GetPageSize( - PULONG size); - - HRESULT GetExecutingProcessorType( - PULONG type); - - HRESULT Execute( - ULONG outputControl, - PCSTR command, - ULONG flags); - - HRESULT GetLastEventInformation( - PULONG type, - PULONG processId, - PULONG threadId, - PVOID extraInformation, - ULONG extraInformationSize, - PULONG extraInformationUsed, - PSTR description, - ULONG descriptionSize, - PULONG descriptionUsed); - - HRESULT Disassemble( - ULONG64 offset, - ULONG flags, - PSTR buffer, - ULONG bufferSize, - PULONG disassemblySize, - PULONG64 endOffset); - - //---------------------------------------------------------------------------- - // IDebugControl4 - //---------------------------------------------------------------------------- - - HRESULT - GetContextStackTrace( - PVOID startContext, - ULONG startContextSize, - PDEBUG_STACK_FRAME frames, - ULONG framesSize, - PVOID frameContexts, - ULONG frameContextsSize, - ULONG frameContextsEntrySize, - PULONG framesFilled); - - //---------------------------------------------------------------------------- - // IDebugDataSpaces - //---------------------------------------------------------------------------- - - HRESULT ReadVirtual( - ULONG64 offset, - PVOID buffer, - ULONG bufferSize, - PULONG bytesRead); - - HRESULT WriteVirtual( - ULONG64 offset, - PVOID buffer, - ULONG bufferSize, - PULONG bytesWritten); - - //---------------------------------------------------------------------------- - // IDebugSymbols - //---------------------------------------------------------------------------- - - HRESULT GetSymbolOptions( - PULONG options); - - HRESULT GetNameByOffset( - ULONG64 offset, - PSTR nameBuffer, - ULONG nameBufferSize, - PULONG nameSize, - PULONG64 displacement); - - HRESULT GetNumberModules( - PULONG loaded, - PULONG unloaded); - - HRESULT GetModuleByIndex( - ULONG index, - PULONG64 base); - - HRESULT GetModuleByModuleName( - PCSTR name, - ULONG startIndex, - PULONG index, - PULONG64 base); - - HRESULT GetModuleByOffset( - ULONG64 offset, - ULONG startIndex, - PULONG index, - PULONG64 base); - - HRESULT GetModuleNames( - ULONG index, - ULONG64 base, - PSTR imageNameBuffer, - ULONG imageNameBufferSize, - PULONG imageNameSize, - PSTR moduleNameBuffer, - ULONG moduleNameBufferSize, - PULONG moduleNameSize, - PSTR loadedImageNameBuffer, - ULONG loadedImageNameBufferSize, - PULONG loadedImageNameSize); - - HRESULT GetLineByOffset( - ULONG64 offset, - PULONG line, - PSTR fileBuffer, - ULONG fileBufferSize, - PULONG fileSize, - PULONG64 displacement); - - HRESULT GetSourceFileLineOffsets( - PCSTR file, - PULONG64 buffer, - ULONG bufferLines, - PULONG fileLines); - - HRESULT FindSourceFile( - ULONG startElement, - PCSTR file, - ULONG flags, - PULONG foundElement, - PSTR buffer, - ULONG bufferSize, - PULONG foundSize); - - //---------------------------------------------------------------------------- - // IDebugSystemObjects - //---------------------------------------------------------------------------- - - HRESULT GetCurrentProcessId( - PULONG id); - - HRESULT GetCurrentThreadId( - PULONG id); - - HRESULT SetCurrentThreadId( - ULONG id); - - HRESULT GetCurrentThreadSystemId( - PULONG sysId); - - HRESULT GetThreadIdBySystemId( - ULONG sysId, - PULONG threadId); - - HRESULT GetThreadContextById( - ULONG32 threadID, - ULONG32 contextFlags, - ULONG32 contextSize, - PBYTE context); - - //---------------------------------------------------------------------------- - // IDebugRegisters - //---------------------------------------------------------------------------- - - HRESULT GetValueByName( - PCSTR name, - PDWORD_PTR debugValue); - - HRESULT GetInstructionOffset( - PULONG64 offset); - - HRESULT GetStackOffset( - PULONG64 offset); - - HRESULT GetFrameOffset( - PULONG64 offset); - - //---------------------------------------------------------------------------- - // LLDBServices (internal) - //---------------------------------------------------------------------------- - - PCSTR GetModuleDirectory( - PCSTR name); -}; diff --git a/src/ToolBox/SOS/lldbplugin/setclrpathcommand.cpp b/src/ToolBox/SOS/lldbplugin/setclrpathcommand.cpp deleted file mode 100644 index 2208306671..0000000000 --- a/src/ToolBox/SOS/lldbplugin/setclrpathcommand.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#include "sosplugin.h" -#include <dlfcn.h> -#include <string.h> -#include <string> -#include <stdlib.h> -#include <limits.h> - -class setclrpathCommand : public lldb::SBCommandPluginInterface -{ -public: - setclrpathCommand() - { - } - - virtual bool - DoExecute (lldb::SBDebugger debugger, - char** arguments, - lldb::SBCommandReturnObject &result) - { - if (arguments[0] == NULL) - { - result.Printf("Load path for sos/dac/dbi: '%s'\n", g_coreclrDirectory == NULL ? "<none>" : g_coreclrDirectory); - } - else { - if (g_coreclrDirectory != NULL) - { - free(g_coreclrDirectory); - } - - std::string path(arguments[0]); - if (path[path.length() - 1] != '/') - { - path.append("/"); - } - - g_coreclrDirectory = strdup(path.c_str()); - result.Printf("Set load path for sos/dac/dbi to '%s'\n", g_coreclrDirectory); - } - return result.Succeeded(); - } -}; - -bool -setclrpathCommandInitialize(lldb::SBDebugger debugger) -{ - lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter(); - lldb::SBCommand command = interpreter.AddCommand("setclrpath", new setclrpathCommand(), "Set the path to load coreclr sos/dac/dbi files. setclrpath <path>"); - return true; -} diff --git a/src/ToolBox/SOS/lldbplugin/setsostidcommand.cpp b/src/ToolBox/SOS/lldbplugin/setsostidcommand.cpp deleted file mode 100644 index 67911e4d10..0000000000 --- a/src/ToolBox/SOS/lldbplugin/setsostidcommand.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#include "sosplugin.h" -#include <dlfcn.h> -#include <string.h> -#include <string> -#include <stdlib.h> -#include <limits.h> - -class setsostidCommand : public lldb::SBCommandPluginInterface -{ -public: - setsostidCommand() - { - } - - virtual bool - DoExecute(lldb::SBDebugger debugger, - char** arguments, - lldb::SBCommandReturnObject &result) - { - if (arguments[0] == NULL) - { - if (g_currentThreadSystemId == (ULONG)-1 || g_currentThreadIndex == (ULONG)-1) - { - result.Printf("sos OS tid not mapped\n"); - } - else { - result.Printf("sos OS tid 0x%x mapped to lldb thread index %d\n", - g_currentThreadSystemId, g_currentThreadIndex); - } - } - else if (strcmp(arguments[0], "-clear") == 0) { - g_currentThreadIndex = (ULONG)-1; - g_currentThreadSystemId = (ULONG)-1; - result.Printf("Cleared sos OS tid/index\n"); - } - else if (arguments[1] == NULL) - { - result.Printf("Need thread index parameter that maps to the OS tid\n"); - } - else - { - ULONG tid = strtoul(arguments[0], NULL, 16); - g_currentThreadSystemId = tid; - - ULONG index = strtoul(arguments[1], NULL, 16); - g_currentThreadIndex = index; - - result.Printf("Mapped sos OS tid 0x%x to lldb thread index %d\n", tid, index); - } - return result.Succeeded(); - } -}; - -bool -setsostidCommandInitialize(lldb::SBDebugger debugger) -{ - lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter(); - lldb::SBCommand command = interpreter.AddCommand("setsostid", new setsostidCommand(), "Set the current os tid/thread index instead of using the one lldb provides. setsostid <tid> <index>"); - return true; -} diff --git a/src/ToolBox/SOS/lldbplugin/soscommand.cpp b/src/ToolBox/SOS/lldbplugin/soscommand.cpp deleted file mode 100644 index da352afd62..0000000000 --- a/src/ToolBox/SOS/lldbplugin/soscommand.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#include "sosplugin.h" -#include <dlfcn.h> -#include <string.h> -#include <string> - -class sosCommand : public lldb::SBCommandPluginInterface -{ - const char *m_command; - void *m_sosHandle; - -public: - sosCommand(const char *command) - { - m_command = command; - m_sosHandle = NULL; - } - - virtual bool - DoExecute (lldb::SBDebugger debugger, - char** arguments, - lldb::SBCommandReturnObject &result) - { - LLDBServices* services = new LLDBServices(debugger, result); - LoadSos(services); - - if (m_sosHandle) - { - const char* sosCommand = m_command; - if (sosCommand == NULL) - { - if (arguments == NULL || *arguments == NULL) { - sosCommand = "Help"; - } - else - { - sosCommand = *arguments++; - } - } - CommandFunc commandFunc = (CommandFunc)dlsym(m_sosHandle, sosCommand); - if (commandFunc) - { - std::string str; - if (arguments != NULL) - { - for (const char* arg = *arguments; arg; arg = *(++arguments)) - { - str.append(arg); - str.append(" "); - } - } - const char* sosArgs = str.c_str(); - HRESULT hr = commandFunc(services, sosArgs); - if (hr != S_OK) - { - services->Output(DEBUG_OUTPUT_ERROR, "%s %s failed\n", sosCommand, sosArgs); - } - } - else - { - services->Output(DEBUG_OUTPUT_ERROR, "SOS command '%s' not found %s\n", sosCommand, dlerror()); - } - } - - services->Release(); - return result.Succeeded(); - } - - void - LoadSos(LLDBServices *services) - { - if (m_sosHandle == NULL) - { - if (g_coreclrDirectory == NULL) - { - const char *coreclrModule = MAKEDLLNAME_A("coreclr"); - const char *directory = services->GetModuleDirectory(coreclrModule); - if (directory != NULL) - { - std::string path(directory); - path.append("/"); - g_coreclrDirectory = strdup(path.c_str()); - } - else - { - services->Output(DEBUG_OUTPUT_WARNING, "The %s module is not loaded yet in the target process\n", coreclrModule); - } - } - - if (g_coreclrDirectory != NULL) - { - // Load the DAC module first explicitly because SOS and DBI - // have implicit references to the DAC's PAL. - LoadModule(services, MAKEDLLNAME_A("mscordaccore")); - - m_sosHandle = LoadModule(services, MAKEDLLNAME_A("sos")); - } - } - } - - void * - LoadModule(LLDBServices *services, const char *moduleName) - { - std::string modulePath(g_coreclrDirectory); - modulePath.append(moduleName); - - void *moduleHandle = dlopen(modulePath.c_str(), RTLD_NOW); - if (moduleHandle == NULL) - { - services->Output(DEBUG_OUTPUT_ERROR, "dlopen(%s) failed %s\n", modulePath.c_str(), dlerror()); - } - - return moduleHandle; - } -}; - -bool -sosCommandInitialize(lldb::SBDebugger debugger) -{ - lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter(); - interpreter.AddCommand("sos", new sosCommand(NULL), "Various coreclr debugging commands. See 'soshelp' for more details. sos <command-name> <args>"); - interpreter.AddCommand("bpmd", new sosCommand("bpmd"), "Creates a breakpoint at the specified managed method in the specified module."); - interpreter.AddCommand("clrstack", new sosCommand("ClrStack"), "Provides a stack trace of managed code only."); - interpreter.AddCommand("clrthreads", new sosCommand("Threads"), "List the managed threads running."); - interpreter.AddCommand("createdump", new sosCommand("CreateDump"), "Create a xplat minidump."); - interpreter.AddCommand("clru", new sosCommand("u"), "Displays an annotated disassembly of a managed method."); - interpreter.AddCommand("dumpasync", new sosCommand("DumpAsync"), "Displays info about async state machines on the garbage-collected heap."); - interpreter.AddCommand("dumpclass", new sosCommand("DumpClass"), "Displays information about a EE class structure at the specified address."); - interpreter.AddCommand("dumpdelegate", new sosCommand("DumpDelegate"), "Displays information about a delegate."); - interpreter.AddCommand("dumpheap", new sosCommand("DumpHeap"), "Displays info about the garbage-collected heap and collection statistics about objects."); - interpreter.AddCommand("dumpil", new sosCommand("DumpIL"), "Displays the Microsoft intermediate language (MSIL) that is associated with a managed method."); - interpreter.AddCommand("dumplog", new sosCommand("DumpLog"), "Writes the contents of an in-memory stress log to the specified file."); - interpreter.AddCommand("dumpmd", new sosCommand("DumpMD"), "Displays information about a MethodDesc structure at the specified address."); - interpreter.AddCommand("dumpmodule", new sosCommand("DumpModule"), "Displays information about a EE module structure at the specified address."); - interpreter.AddCommand("dumpmt", new sosCommand("DumpMT"), "Displays information about a method table at the specified address."); - interpreter.AddCommand("dumpobj", new sosCommand("DumpObj"), "Displays info about an object at the specified address."); - interpreter.AddCommand("dumpstack", new sosCommand("DumpStack"), "Displays a native and managed stack trace."); - interpreter.AddCommand("dso", new sosCommand("DumpStackObjects"), "Displays all managed objects found within the bounds of the current stack."); - interpreter.AddCommand("eeheap", new sosCommand("EEHeap"), "Displays info about process memory consumed by internal runtime data structures."); - interpreter.AddCommand("eestack", new sosCommand("EEStack"), "Runs dumpstack on all threads in the process."); - interpreter.AddCommand("finalizequeue", new sosCommand("FinalizeQueue"), "Displays all objects registered for finalization."); - interpreter.AddCommand("gcroot", new sosCommand("GCRoot"), "Displays info about references (or roots) to an object at the specified address."); - interpreter.AddCommand("ip2md", new sosCommand("IP2MD"), "Displays the MethodDesc structure at the specified address in code that has been JIT-compiled."); - interpreter.AddCommand("name2ee", new sosCommand("Name2EE"), "Displays the MethodTable structure and EEClass structure for the specified type or method in the specified module."); - interpreter.AddCommand("pe", new sosCommand("PrintException"), "Displays and formats fields of any object derived from the Exception class at the specified address."); - interpreter.AddCommand("syncblk", new sosCommand("SyncBlk"), "Displays the SyncBlock holder info."); - interpreter.AddCommand("histclear", new sosCommand("HistClear"), "Releases any resources used by the family of Hist commands."); - interpreter.AddCommand("histinit", new sosCommand("HistInit"), "Initializes the SOS structures from the stress log saved in the debuggee."); - interpreter.AddCommand("histobj", new sosCommand("HistObj"), "Examines all stress log relocation records and displays the chain of garbage collection relocations that may have led to the address passed in as an argument."); - interpreter.AddCommand("histobjfind", new sosCommand("HistObjFind"), "Displays all the log entries that reference an object at the specified address."); - interpreter.AddCommand("histroot", new sosCommand("HistRoot"), "Displays information related to both promotions and relocations of the specified root."); - interpreter.AddCommand("soshelp", new sosCommand("Help"), "Displays all available commands when no parameter is specified, or displays detailed help information about the specified command. soshelp <command>"); - return true; -} diff --git a/src/ToolBox/SOS/lldbplugin/sosplugin.cpp b/src/ToolBox/SOS/lldbplugin/sosplugin.cpp deleted file mode 100644 index f575d0de91..0000000000 --- a/src/ToolBox/SOS/lldbplugin/sosplugin.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#include "sosplugin.h" - -namespace lldb { - DLLEXPORT bool PluginInitialize (lldb::SBDebugger debugger); -} - -bool -lldb::PluginInitialize (lldb::SBDebugger debugger) -{ - sosCommandInitialize(debugger); - setclrpathCommandInitialize(debugger); - setsostidCommandInitialize(debugger); - return true; -} diff --git a/src/ToolBox/SOS/lldbplugin/sosplugin.h b/src/ToolBox/SOS/lldbplugin/sosplugin.h deleted file mode 100644 index 588ec468e2..0000000000 --- a/src/ToolBox/SOS/lldbplugin/sosplugin.h +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#include <lldb/API/LLDB.h> -#include "mstypes.h" -#define DEFINE_EXCEPTION_RECORD -#include <lldbservices.h> -#include <dbgtargetcontext.h> -#include "services.h" - -typedef HRESULT (*CommandFunc)(ILLDBServices* services, const char *args); - -extern char *g_coreclrDirectory; -extern ULONG g_currentThreadIndex; -extern ULONG g_currentThreadSystemId; - -bool -sosCommandInitialize(lldb::SBDebugger debugger); - -bool -setsostidCommandInitialize(lldb::SBDebugger debugger); - -bool -setclrpathCommandInitialize(lldb::SBDebugger debugger); |