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
20Notes:
21
22HRESULT CALLBACK _EFN_StackTrace(
23 PDEBUG_CLIENT client,
24 WCHAR wszTextOut[],
25 UINT *puiTextLength,
26 LPVOID pTransitionContexts,
27 UINT *puiTransitionContextCount,
28 UINT uiSizeOfContext);
29
30uiSizeOfContext must be either sizeof(SimpleContext) or sizeof(CONTEXT) for the
31architecture (x86, IA64, x64).
32
33if wszTextOut is NULL and *puiTextLength is non-NULL, the function will return
34the necessary string length in *puiTextLength.
35
36If wszTextOut is non-NULL, the function will fill wszTextOut up to the point
37given by *puiTextLength, returning success if there was enough room in the
38buffer or E_OUTOFMEMORY if the buffer wasn't long enough.
39
40The transition portion of the function will be completely ignored if
41pTransitionContexts and puiTransitionContextCount are both NULL. Some callers
42would just like text output of the function names.
43
44If pTransitionContexts is NULL and puiTransitionContextCount is non NULL, the
45function will return the necessary number of context entries in
46*puiTransitionContextCount.
47
48If pTransitionContexts is non NULL, the function will treat it as an array of
49structures of length *puiTransitionContextCount. The structure size is given
50by uiSizeOfContext, and must be the size of SimpleContext or CONTEXT for the
51architecture.
52
53wszTextOut will be written in the following format:
54
55"<ModuleName>!<Function Name>[+<offset in hex>]
56...
57(TRANSITION)
58..."
59
60if the offset in hex is 0, no offset will be written (this matches KB output).
61
62If there is no managed code on the thread currently in context,
63SOS_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
87struct StackTrace_SimpleContext
88{
89 ULONG64 StackOffset; // esp on x86
90 ULONG64 FrameOffset; // ebp
91 ULONG64 InstructionOffset; // eip
92};
93
94#ifdef __cplusplus
95extern "C" {
96#endif // __cplusplus
97
98HRESULT 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.
122HRESULT 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.
131HRESULT 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//
144HRESULT 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.
161HRESULT 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