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 | |
8 | // |
9 | // ==--== |
10 | /* --------------------------------------------------------------------------- |
11 | |
12 | SOS_Stacktrace.h |
13 | |
14 | API exported from SOS.DLL for retrieving managed stack traces. |
15 | This extension function is called through the Windows Debugger extension |
16 | interfaces (dbgeng.h). |
17 | |
18 | Additional functions exported from SOS are documented here as well. |
19 | |
20 | Notes: |
21 | |
22 | HRESULT CALLBACK _EFN_StackTrace( |
23 | PDEBUG_CLIENT client, |
24 | WCHAR wszTextOut[], |
25 | UINT *puiTextLength, |
26 | LPVOID pTransitionContexts, |
27 | UINT *puiTransitionContextCount, |
28 | UINT uiSizeOfContext); |
29 | |
30 | uiSizeOfContext must be either sizeof(SimpleContext) or sizeof(CONTEXT) for the |
31 | architecture (x86, IA64, x64). |
32 | |
33 | if wszTextOut is NULL and *puiTextLength is non-NULL, the function will return |
34 | the necessary string length in *puiTextLength. |
35 | |
36 | If wszTextOut is non-NULL, the function will fill wszTextOut up to the point |
37 | given by *puiTextLength, returning success if there was enough room in the |
38 | buffer or E_OUTOFMEMORY if the buffer wasn't long enough. |
39 | |
40 | The transition portion of the function will be completely ignored if |
41 | pTransitionContexts and puiTransitionContextCount are both NULL. Some callers |
42 | would just like text output of the function names. |
43 | |
44 | If pTransitionContexts is NULL and puiTransitionContextCount is non NULL, the |
45 | function will return the necessary number of context entries in |
46 | *puiTransitionContextCount. |
47 | |
48 | If pTransitionContexts is non NULL, the function will treat it as an array of |
49 | structures of length *puiTransitionContextCount. The structure size is given |
50 | by uiSizeOfContext, and must be the size of SimpleContext or CONTEXT for the |
51 | architecture. |
52 | |
53 | wszTextOut will be written in the following format: |
54 | |
55 | "<ModuleName>!<Function Name>[+<offset in hex>] |
56 | ... |
57 | (TRANSITION) |
58 | ..." |
59 | |
60 | if the offset in hex is 0, no offset will be written (this matches KB output). |
61 | |
62 | If there is no managed code on the thread currently in context, |
63 | SOS_E_NOMANAGEDCODE will be returned. |
64 | ------------------------------------------------------------------------ */ |
65 | #ifndef __STACKTRACE_H |
66 | #define __STACKTRACE_H |
67 | #include <windows.h> |
68 | #include <winerror.h> |
69 | |
70 | #ifndef FACILITY_SOS |
71 | #define FACILITY_SOS 0xa0 |
72 | #endif |
73 | |
74 | #ifndef EMAKEHR |
75 | #define EMAKEHR(val) MAKE_HRESULT(SEVERITY_ERROR, FACILITY_SOS, val) |
76 | #endif |
77 | |
78 | // Custom Error returns |
79 | #define SOS_E_NOMANAGEDCODE EMAKEHR(0x1000) // No managed code on the stack |
80 | |
81 | // Flags |
82 | // |
83 | // Turn on SOS_STACKTRACE_SHOWADDRESSES to see EBP ESP in front of each |
84 | // module!functionname line. By default this is off. |
85 | #define SOS_STACKTRACE_SHOWADDRESSES 0x00000001 |
86 | |
87 | struct StackTrace_SimpleContext |
88 | { |
89 | ULONG64 StackOffset; // esp on x86 |
90 | ULONG64 FrameOffset; // ebp |
91 | ULONG64 InstructionOffset; // eip |
92 | }; |
93 | |
94 | #ifdef __cplusplus |
95 | extern "C" { |
96 | #endif // __cplusplus |
97 | |
98 | HRESULT CALLBACK _EFN_StackTrace( |
99 | PDEBUG_CLIENT client, |
100 | __out_ecount(*puiTextLength) WCHAR wszTextOut[], |
101 | size_t *puiTextLength, |
102 | LPVOID pTransitionContexts, |
103 | size_t *puiTransitionContextCount, |
104 | size_t uiSizeOfContext, |
105 | DWORD Flags); |
106 | |
107 | /* --------------------------------------------------------------------------- |
108 | |
109 | Additional functions are exported from SOS, and are useful |
110 | for debugging tasks with managed object pointers. |
111 | |
112 | ------------------------------------------------------------------------ */ |
113 | |
114 | // _EFN_GetManagedExcepStack - given a managed exception object address, returns a string |
115 | // version of the stack trace contained inside. |
116 | // |
117 | // StackObjAddr - a managed object pointer, must be derived from System.Exception |
118 | // szStackString - the string returned (out parameter) |
119 | // cbString - number of characters available in the string buffer. |
120 | // |
121 | // The output will be truncated of cbString is not long enough for the full stack trace. |
122 | HRESULT CALLBACK _EFN_GetManagedExcepStack( |
123 | PDEBUG_CLIENT client, |
124 | ULONG64 StackObjAddr, |
125 | __out_ecount(cbString) PSTR szStackString, |
126 | ULONG cbString |
127 | ); |
128 | |
129 | // _EFN_GetManagedExcepStackW - same as _EFN_GetManagedExcepStack, but returns |
130 | // the stack as a wide string. |
131 | HRESULT CALLBACK _EFN_GetManagedExcepStackW( |
132 | PDEBUG_CLIENT client, |
133 | ULONG64 StackObjAddr, |
134 | __out_ecount(cchString) PWSTR wszStackString, |
135 | ULONG cchString |
136 | ); |
137 | |
138 | // _EFN_GetManagedObjectName - given a managed object pointer, return the type name |
139 | // |
140 | // objAddr - a managed object pointer |
141 | // szName - a buffer to be filled with the full type name |
142 | // cbName - the number of characters available in the buffer |
143 | // |
144 | HRESULT CALLBACK _EFN_GetManagedObjectName( |
145 | PDEBUG_CLIENT client, |
146 | ULONG64 objAddr, |
147 | __out_ecount(cbName) PSTR szName, |
148 | ULONG cbName |
149 | ); |
150 | |
151 | // _EFN_GetManagedObjectFieldInfo - given an object pointer and a field name, returns |
152 | // the offset to the field from the start of the object, |
153 | // and the field's value. |
154 | // |
155 | // objAddr - a managed object pointer |
156 | // szFieldName - the field name you are interested in |
157 | // pValue - the field value is written here. This parameter can be NULL. |
158 | // pOffset - the offset from objAddr to the field. This parameter can be NULL. |
159 | // |
160 | // At least one of pValue and pOffset must be non-NULL. |
161 | HRESULT CALLBACK _EFN_GetManagedObjectFieldInfo( |
162 | PDEBUG_CLIENT client, |
163 | ULONG64 objAddr, |
164 | __out_ecount (mdNameLen) PSTR szFieldName, |
165 | PULONG64 pValue, |
166 | PULONG pOffset |
167 | ); |
168 | |
169 | #ifdef __cplusplus |
170 | } |
171 | #endif // __cplusplus : extern "C" |
172 | |
173 | #endif // __STACKTRACE_H |
174 | |
175 | |