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 | |