| 1 | // Licensed to the .NET Foundation under one or more agreements. |
| 2 | // The .NET Foundation licenses this file to you under the MIT license. |
| 3 | // See the LICENSE file in the project root for more information. |
| 4 | |
| 5 | //---------------------------------------------------------------------------- |
| 6 | // |
| 7 | // Debugger engine interface subset implemented with ILLDBServices |
| 8 | // |
| 9 | //---------------------------------------------------------------------------- |
| 10 | |
| 11 | #ifndef __DBGENG_H__ |
| 12 | #define __DBGENG_H__ |
| 13 | |
| 14 | #include <unknwn.h> |
| 15 | #include <rpc.h> |
| 16 | #include <lldbservices.h> |
| 17 | |
| 18 | #ifdef __cplusplus |
| 19 | extern "C" { |
| 20 | #endif |
| 21 | |
| 22 | class DebugClient |
| 23 | { |
| 24 | private: |
| 25 | LONG m_ref; |
| 26 | ILLDBServices *m_lldbservices; |
| 27 | |
| 28 | public: |
| 29 | DebugClient(ILLDBServices *lldbservices) : |
| 30 | m_ref(1), |
| 31 | m_lldbservices(lldbservices) |
| 32 | { |
| 33 | m_lldbservices->AddRef(); |
| 34 | } |
| 35 | |
| 36 | //---------------------------------------------------------------------------- |
| 37 | // IUnknown |
| 38 | //---------------------------------------------------------------------------- |
| 39 | |
| 40 | HRESULT |
| 41 | QueryInterface( |
| 42 | REFIID InterfaceId, |
| 43 | PVOID* Interface); |
| 44 | |
| 45 | ULONG AddRef(); |
| 46 | |
| 47 | ULONG Release(); |
| 48 | |
| 49 | //---------------------------------------------------------------------------- |
| 50 | // IDebugControl2 |
| 51 | //---------------------------------------------------------------------------- |
| 52 | |
| 53 | // Checks for a user interrupt, such a Ctrl-C |
| 54 | // or stop button. |
| 55 | // This method is reentrant. |
| 56 | HRESULT |
| 57 | GetInterrupt() |
| 58 | { |
| 59 | return m_lldbservices->GetInterrupt(); |
| 60 | } |
| 61 | |
| 62 | // Sends output through clients |
| 63 | // output callbacks if the mask is allowed |
| 64 | // by the current output control mask and |
| 65 | // according to the output distribution |
| 66 | // settings. |
| 67 | HRESULT |
| 68 | Output( |
| 69 | ULONG mask, |
| 70 | PCSTR format, |
| 71 | ...) |
| 72 | { |
| 73 | va_list args; |
| 74 | va_start (args, format); |
| 75 | HRESULT result = m_lldbservices->OutputVaList(mask, format, args); |
| 76 | va_end (args); |
| 77 | return result; |
| 78 | } |
| 79 | |
| 80 | HRESULT |
| 81 | OutputVaList( |
| 82 | ULONG mask, |
| 83 | PCSTR format, |
| 84 | va_list args) |
| 85 | { |
| 86 | char str[4096]; |
| 87 | int length = _vsnprintf_s(str, sizeof(str), _TRUNCATE, format, args); |
| 88 | if (length > 0) |
| 89 | { |
| 90 | return Output(mask, "%s" , str); |
| 91 | } |
| 92 | return E_FAIL; |
| 93 | } |
| 94 | |
| 95 | // The following methods allow direct control |
| 96 | // over the distribution of the given output |
| 97 | // for situations where something other than |
| 98 | // the default is desired. These methods require |
| 99 | // extra work in the engine so they should |
| 100 | // only be used when necessary. |
| 101 | HRESULT |
| 102 | ControlledOutput( |
| 103 | ULONG outputControl, |
| 104 | ULONG mask, |
| 105 | PCSTR format, |
| 106 | ...) |
| 107 | { |
| 108 | va_list args; |
| 109 | va_start (args, format); |
| 110 | HRESULT result = ControlledOutputVaList(outputControl, mask, format, args); |
| 111 | va_end (args); |
| 112 | return result; |
| 113 | } |
| 114 | |
| 115 | HRESULT |
| 116 | ControlledOutputVaList( |
| 117 | ULONG outputControl, |
| 118 | ULONG mask, |
| 119 | PCSTR format, |
| 120 | va_list args) |
| 121 | { |
| 122 | return OutputVaList(mask, format, args); |
| 123 | } |
| 124 | |
| 125 | // Returns information about the debuggee such |
| 126 | // as user vs. kernel, dump vs. live, etc. |
| 127 | HRESULT |
| 128 | GetDebuggeeType( |
| 129 | PULONG debugClass, |
| 130 | PULONG qualifier) |
| 131 | { |
| 132 | return m_lldbservices->GetDebuggeeType(debugClass, qualifier); |
| 133 | } |
| 134 | |
| 135 | // Returns the page size for the currently executing |
| 136 | // processor context. The page size may vary between |
| 137 | // processor types. |
| 138 | HRESULT |
| 139 | GetPageSize( |
| 140 | PULONG size) |
| 141 | { |
| 142 | return m_lldbservices->GetPageSize(size); |
| 143 | } |
| 144 | |
| 145 | HRESULT |
| 146 | GetExecutingProcessorType( |
| 147 | PULONG type) |
| 148 | { |
| 149 | return m_lldbservices->GetExecutingProcessorType(type); |
| 150 | } |
| 151 | |
| 152 | HRESULT |
| 153 | Execute( |
| 154 | ULONG outputControl, |
| 155 | PCSTR command, |
| 156 | ULONG flags) |
| 157 | { |
| 158 | return m_lldbservices->Execute(outputControl, command, flags); |
| 159 | } |
| 160 | |
| 161 | HRESULT |
| 162 | GetLastEventInformation( |
| 163 | PULONG type, |
| 164 | PULONG processId, |
| 165 | PULONG threadId, |
| 166 | PVOID , |
| 167 | ULONG , |
| 168 | PULONG , |
| 169 | PSTR description, |
| 170 | ULONG descriptionSize, |
| 171 | PULONG descriptionUsed) |
| 172 | { |
| 173 | return m_lldbservices->GetLastEventInformation(type, processId, threadId, extraInformation, |
| 174 | extraInformationSize, extraInformationUsed, description, descriptionSize, descriptionUsed); |
| 175 | } |
| 176 | |
| 177 | HRESULT |
| 178 | Disassemble( |
| 179 | ULONG64 offset, |
| 180 | ULONG flags, |
| 181 | PSTR buffer, |
| 182 | ULONG bufferSize, |
| 183 | PULONG disassemblySize, |
| 184 | PULONG64 endOffset) |
| 185 | { |
| 186 | return m_lldbservices->Disassemble(offset, flags, buffer, bufferSize, disassemblySize, endOffset); |
| 187 | } |
| 188 | |
| 189 | //---------------------------------------------------------------------------- |
| 190 | // IDebugControl4 |
| 191 | //---------------------------------------------------------------------------- |
| 192 | |
| 193 | // Stack tracing with a full initial context |
| 194 | // and full context return for each frame. |
| 195 | // The FrameContextsSize parameter is the total |
| 196 | // byte size of FrameContexts. FrameContextsEntrySize |
| 197 | // gives the byte size of each entry in |
| 198 | // FrameContexts. |
| 199 | HRESULT |
| 200 | GetContextStackTrace( |
| 201 | PVOID startContext, |
| 202 | ULONG startContextSize, |
| 203 | PDEBUG_STACK_FRAME frames, |
| 204 | ULONG framesSize, |
| 205 | PVOID frameContexts, |
| 206 | ULONG frameContextsSize, |
| 207 | ULONG frameContextsEntrySize, |
| 208 | PULONG framesFilled) |
| 209 | { |
| 210 | return m_lldbservices->GetContextStackTrace(startContext, startContextSize, frames, |
| 211 | framesSize, frameContexts, frameContextsSize, frameContextsEntrySize, framesFilled); |
| 212 | } |
| 213 | |
| 214 | //---------------------------------------------------------------------------- |
| 215 | // IDebugDataSpaces |
| 216 | //---------------------------------------------------------------------------- |
| 217 | |
| 218 | HRESULT |
| 219 | ReadVirtual( |
| 220 | ULONG64 offset, |
| 221 | PVOID buffer, |
| 222 | ULONG bufferSize, |
| 223 | PULONG bytesRead) |
| 224 | { |
| 225 | return m_lldbservices->ReadVirtual(offset, buffer, bufferSize, bytesRead); |
| 226 | } |
| 227 | |
| 228 | HRESULT |
| 229 | WriteVirtual( |
| 230 | ULONG64 offset, |
| 231 | PVOID buffer, |
| 232 | ULONG bufferSize, |
| 233 | PULONG bytesWritten) |
| 234 | { |
| 235 | return m_lldbservices->WriteVirtual(offset, buffer, bufferSize, bytesWritten); |
| 236 | } |
| 237 | |
| 238 | //---------------------------------------------------------------------------- |
| 239 | // IDebugSymbols |
| 240 | //---------------------------------------------------------------------------- |
| 241 | |
| 242 | HRESULT |
| 243 | GetSymbolOptions( |
| 244 | PULONG options) |
| 245 | { |
| 246 | return m_lldbservices->GetSymbolOptions(options); |
| 247 | } |
| 248 | |
| 249 | HRESULT |
| 250 | GetNameByOffset( |
| 251 | ULONG64 offset, |
| 252 | PSTR nameBuffer, |
| 253 | ULONG nameBufferSize, |
| 254 | PULONG nameSize, |
| 255 | PULONG64 displacement) |
| 256 | { |
| 257 | return m_lldbservices->GetNameByOffset(offset, nameBuffer, nameBufferSize, nameSize, displacement); |
| 258 | } |
| 259 | |
| 260 | HRESULT |
| 261 | GetNumberModules( |
| 262 | PULONG loaded, |
| 263 | PULONG unloaded) |
| 264 | { |
| 265 | return m_lldbservices->GetNumberModules(loaded, unloaded); |
| 266 | } |
| 267 | |
| 268 | HRESULT GetModuleByIndex( |
| 269 | ULONG index, |
| 270 | PULONG64 base) |
| 271 | { |
| 272 | return m_lldbservices->GetModuleByIndex(index, base); |
| 273 | } |
| 274 | |
| 275 | HRESULT |
| 276 | GetModuleByModuleName( |
| 277 | PCSTR name, |
| 278 | ULONG startIndex, |
| 279 | PULONG index, |
| 280 | PULONG64 base) |
| 281 | { |
| 282 | return m_lldbservices->GetModuleByModuleName(name, startIndex, index, base); |
| 283 | } |
| 284 | |
| 285 | HRESULT |
| 286 | GetModuleByOffset( |
| 287 | ULONG64 offset, |
| 288 | ULONG startIndex, |
| 289 | PULONG index, |
| 290 | PULONG64 base) |
| 291 | { |
| 292 | return m_lldbservices->GetModuleByOffset(offset, startIndex, index, base); |
| 293 | } |
| 294 | |
| 295 | HRESULT |
| 296 | GetModuleNames( |
| 297 | ULONG index, |
| 298 | ULONG64 base, |
| 299 | PSTR imageNameBuffer, |
| 300 | ULONG imageNameBufferSize, |
| 301 | PULONG imageNameSize, |
| 302 | PSTR moduleNameBuffer, |
| 303 | ULONG moduleNameBufferSize, |
| 304 | PULONG moduleNameSize, |
| 305 | PSTR loadedImageNameBuffer, |
| 306 | ULONG loadedImageNameBufferSize, |
| 307 | PULONG loadedImageNameSize) |
| 308 | { |
| 309 | return m_lldbservices->GetModuleNames(index, base, imageNameBuffer, imageNameBufferSize, imageNameSize, moduleNameBuffer, |
| 310 | moduleNameBufferSize, moduleNameSize, loadedImageNameBuffer, loadedImageNameBufferSize, loadedImageNameSize); |
| 311 | } |
| 312 | |
| 313 | HRESULT |
| 314 | GetLineByOffset( |
| 315 | ULONG64 offset, |
| 316 | PULONG line, |
| 317 | PSTR fileBuffer, |
| 318 | ULONG fileBufferSize, |
| 319 | PULONG fileSize, |
| 320 | PULONG64 displacement) |
| 321 | { |
| 322 | return m_lldbservices->GetLineByOffset(offset, line, fileBuffer, fileBufferSize, fileSize, displacement); |
| 323 | } |
| 324 | |
| 325 | HRESULT |
| 326 | GetSourceFileLineOffsets( |
| 327 | PCSTR file, |
| 328 | PULONG64 buffer, |
| 329 | ULONG bufferLines, |
| 330 | PULONG fileLines) |
| 331 | { |
| 332 | return m_lldbservices->GetSourceFileLineOffsets(file, buffer, bufferLines, fileLines); |
| 333 | } |
| 334 | |
| 335 | // Uses the given file path and the source path |
| 336 | // information to try and locate an existing file. |
| 337 | // The given file path is merged with elements |
| 338 | // of the source path and checked for existence. |
| 339 | // If a match is found the element used is returned. |
| 340 | // A starting element can be specified to restrict |
| 341 | // the search to a subset of the path elements; |
| 342 | // this can be useful when checking for multiple |
| 343 | // matches along the source path. |
| 344 | // The returned element can be 1, indicating |
| 345 | // the file was found directly and not on the path. |
| 346 | HRESULT |
| 347 | FindSourceFile( |
| 348 | ULONG startElement, |
| 349 | PCSTR file, |
| 350 | ULONG flags, |
| 351 | PULONG foundElement, |
| 352 | PSTR buffer, |
| 353 | ULONG bufferSize, |
| 354 | PULONG foundSize) |
| 355 | { |
| 356 | return m_lldbservices->FindSourceFile(startElement, file, flags, foundElement, buffer, bufferSize, foundSize); |
| 357 | } |
| 358 | |
| 359 | //---------------------------------------------------------------------------- |
| 360 | // IDebugSystemObjects |
| 361 | //---------------------------------------------------------------------------- |
| 362 | |
| 363 | HRESULT |
| 364 | GetCurrentProcessId( |
| 365 | PULONG id) |
| 366 | { |
| 367 | return m_lldbservices->GetCurrentProcessId(id); |
| 368 | } |
| 369 | |
| 370 | HRESULT |
| 371 | GetCurrentThreadId( |
| 372 | PULONG id) |
| 373 | { |
| 374 | return m_lldbservices->GetCurrentThreadId(id); |
| 375 | } |
| 376 | |
| 377 | HRESULT |
| 378 | SetCurrentThreadId( |
| 379 | ULONG id) |
| 380 | { |
| 381 | return m_lldbservices->SetCurrentThreadId(id); |
| 382 | } |
| 383 | |
| 384 | HRESULT |
| 385 | GetCurrentThreadSystemId( |
| 386 | PULONG sysId) |
| 387 | { |
| 388 | return m_lldbservices->GetCurrentThreadSystemId(sysId); |
| 389 | } |
| 390 | |
| 391 | HRESULT |
| 392 | GetThreadIdBySystemId( |
| 393 | ULONG sysId, |
| 394 | PULONG threadId) |
| 395 | { |
| 396 | return m_lldbservices->GetThreadIdBySystemId(sysId, threadId); |
| 397 | } |
| 398 | |
| 399 | HRESULT |
| 400 | GetThreadContextById( |
| 401 | /* in */ ULONG32 threadID, |
| 402 | /* in */ ULONG32 contextFlags, |
| 403 | /* in */ ULONG32 contextSize, |
| 404 | /* out */ PBYTE context) |
| 405 | { |
| 406 | return m_lldbservices->GetThreadContextById(threadID, contextFlags, contextSize, context); |
| 407 | } |
| 408 | |
| 409 | //---------------------------------------------------------------------------- |
| 410 | // IDebugRegisters |
| 411 | //---------------------------------------------------------------------------- |
| 412 | |
| 413 | HRESULT |
| 414 | GetValueByName( |
| 415 | PCSTR name, |
| 416 | PDWORD_PTR debugValue) |
| 417 | { |
| 418 | return m_lldbservices->GetValueByName(name, debugValue); |
| 419 | } |
| 420 | |
| 421 | HRESULT |
| 422 | GetInstructionOffset( |
| 423 | PULONG64 offset) |
| 424 | { |
| 425 | return m_lldbservices->GetInstructionOffset(offset); |
| 426 | } |
| 427 | |
| 428 | HRESULT |
| 429 | GetStackOffset( |
| 430 | PULONG64 offset) |
| 431 | { |
| 432 | return m_lldbservices->GetStackOffset(offset); |
| 433 | } |
| 434 | |
| 435 | HRESULT |
| 436 | GetFrameOffset( |
| 437 | PULONG64 offset) |
| 438 | { |
| 439 | return m_lldbservices->GetFrameOffset(offset); |
| 440 | } |
| 441 | }; |
| 442 | |
| 443 | MIDL_INTERFACE("d4366723-44df-4bed-8c7e-4c05424f4588" ) |
| 444 | IDebugControl2 : DebugClient |
| 445 | { |
| 446 | }; |
| 447 | |
| 448 | MIDL_INTERFACE("94e60ce9-9b41-4b19-9fc0-6d9eb35272b3" ) |
| 449 | IDebugControl4 : DebugClient |
| 450 | { |
| 451 | }; |
| 452 | |
| 453 | MIDL_INTERFACE("88f7dfab-3ea7-4c3a-aefb-c4e8106173aa" ) |
| 454 | IDebugDataSpaces : DebugClient |
| 455 | { |
| 456 | }; |
| 457 | |
| 458 | MIDL_INTERFACE("8c31e98c-983a-48a5-9016-6fe5d667a950" ) |
| 459 | IDebugSymbols : DebugClient |
| 460 | { |
| 461 | }; |
| 462 | |
| 463 | MIDL_INTERFACE("6b86fe2c-2c4f-4f0c-9da2-174311acc327" ) |
| 464 | IDebugSystemObjects : DebugClient |
| 465 | { |
| 466 | }; |
| 467 | |
| 468 | MIDL_INTERFACE("ce289126-9e84-45a7-937e-67bb18691493" ) |
| 469 | IDebugRegisters : DebugClient |
| 470 | { |
| 471 | }; |
| 472 | |
| 473 | typedef interface ILLDBServices* PDEBUG_CLIENT; |
| 474 | typedef interface IDebugControl2* PDEBUG_CONTROL2; |
| 475 | typedef interface IDebugControl4* PDEBUG_CONTROL4; |
| 476 | typedef interface IDebugDataSpaces* PDEBUG_DATA_SPACES; |
| 477 | typedef interface IDebugSymbols* PDEBUG_SYMBOLS; |
| 478 | typedef interface IDebugSystemObjects* PDEBUG_SYSTEM_OBJECTS; |
| 479 | typedef interface IDebugRegisters* PDEBUG_REGISTERS; |
| 480 | |
| 481 | #ifdef __cplusplus |
| 482 | }; |
| 483 | #endif |
| 484 | |
| 485 | #endif // #ifndef __DBGENG_H__ |
| 486 | |