sedna 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{CHANGES → CHANGES.rdoc} +9 -0
- data/{README → README.rdoc} +23 -25
- data/Rakefile +32 -9
- data/ext/{extconf.rb → sedna/extconf.rb} +33 -21
- data/ext/{sedna.c → sedna/sedna.c} +48 -40
- data/test/sedna_test.rb +9 -9
- data/vendor/sedna/AUTHORS +18 -0
- data/vendor/sedna/COPYRIGHT +90 -0
- data/vendor/sedna/LICENSE +202 -0
- data/vendor/sedna/Makefile.include +423 -0
- data/vendor/sedna/Makefile.platform +31 -0
- data/vendor/sedna/depend.sed +48 -0
- data/vendor/sedna/driver/c/Makefile +98 -0
- data/vendor/sedna/driver/c/libsedna.c +1998 -0
- data/vendor/sedna/driver/c/libsedna.h +199 -0
- data/vendor/sedna/driver/c/sednamt.def +21 -0
- data/vendor/sedna/driver/c/sp_defs.h +186 -0
- data/vendor/sedna/kernel/common/FastXptrHash.cpp +101 -0
- data/vendor/sedna/kernel/common/IntHash.h +314 -0
- data/vendor/sedna/kernel/common/IntList.h +224 -0
- data/vendor/sedna/kernel/common/Makefile +30 -0
- data/vendor/sedna/kernel/common/SSMMsg.cpp +459 -0
- data/vendor/sedna/kernel/common/SSMMsg.h +142 -0
- data/vendor/sedna/kernel/common/XptrHash.h +435 -0
- data/vendor/sedna/kernel/common/argtable.c +972 -0
- data/vendor/sedna/kernel/common/argtable.h +896 -0
- data/vendor/sedna/kernel/common/base.cpp +339 -0
- data/vendor/sedna/kernel/common/base.h +226 -0
- data/vendor/sedna/kernel/common/bit_set.cpp +157 -0
- data/vendor/sedna/kernel/common/bit_set.h +55 -0
- data/vendor/sedna/kernel/common/commutil.h +67 -0
- data/vendor/sedna/kernel/common/config.h +62 -0
- data/vendor/sedna/kernel/common/counted_ptr.h +74 -0
- data/vendor/sedna/kernel/common/errdbg/ErrorCodes.java +1056 -0
- data/vendor/sedna/kernel/common/errdbg/Makefile +34 -0
- data/vendor/sedna/kernel/common/errdbg/assert.c +133 -0
- data/vendor/sedna/kernel/common/errdbg/d_printf.c +150 -0
- data/vendor/sedna/kernel/common/errdbg/d_printf.h +91 -0
- data/vendor/sedna/kernel/common/errdbg/error.codes +1743 -0
- data/vendor/sedna/kernel/common/errdbg/error_codes.c +531 -0
- data/vendor/sedna/kernel/common/errdbg/error_codes.h +549 -0
- data/vendor/sedna/kernel/common/errdbg/error_codes_scm.scm +527 -0
- data/vendor/sedna/kernel/common/errdbg/event_log.c +956 -0
- data/vendor/sedna/kernel/common/errdbg/event_log.h +226 -0
- data/vendor/sedna/kernel/common/errdbg/exceptions.cpp +155 -0
- data/vendor/sedna/kernel/common/errdbg/exceptions.h +559 -0
- data/vendor/sedna/kernel/common/errdbg/gen_error_codes +0 -0
- data/vendor/sedna/kernel/common/errdbg/gen_error_codes.c +345 -0
- data/vendor/sedna/kernel/common/gmm.cpp +192 -0
- data/vendor/sedna/kernel/common/gmm.h +29 -0
- data/vendor/sedna/kernel/common/ipc_ops.cpp +435 -0
- data/vendor/sedna/kernel/common/ipc_ops.h +51 -0
- data/vendor/sedna/kernel/common/lfsGlobals.h +12 -0
- data/vendor/sedna/kernel/common/lm_base.h +90 -0
- data/vendor/sedna/kernel/common/mmgr/Makefile +11 -0
- data/vendor/sedna/kernel/common/mmgr/aset.c +1185 -0
- data/vendor/sedna/kernel/common/mmgr/mcxt.c +741 -0
- data/vendor/sedna/kernel/common/mmgr/memnodes.h +70 -0
- data/vendor/sedna/kernel/common/mmgr/memutils.h +145 -0
- data/vendor/sedna/kernel/common/mmgr/se_alloc.h +321 -0
- data/vendor/sedna/kernel/common/mmgr/track.c +214 -0
- data/vendor/sedna/kernel/common/pping.cpp +672 -0
- data/vendor/sedna/kernel/common/pping.h +119 -0
- data/vendor/sedna/kernel/common/rcv_test.cpp +273 -0
- data/vendor/sedna/kernel/common/rcv_test.h +19 -0
- data/vendor/sedna/kernel/common/sedna.c +128 -0
- data/vendor/sedna/kernel/common/sedna.h +49 -0
- data/vendor/sedna/kernel/common/sedna_ef.h +52 -0
- data/vendor/sedna/kernel/common/sm_vmm_data.h +144 -0
- data/vendor/sedna/kernel/common/sp.c +93 -0
- data/vendor/sedna/kernel/common/sp.h +36 -0
- data/vendor/sedna/kernel/common/st/Makefile +20 -0
- data/vendor/sedna/kernel/common/st/os_linux/stacktrace.c +213 -0
- data/vendor/sedna/kernel/common/st/os_nt/stacktrace.c +338 -0
- data/vendor/sedna/kernel/common/st/os_other/stacktrace.c +39 -0
- data/vendor/sedna/kernel/common/st/stacktrace.h +72 -0
- data/vendor/sedna/kernel/common/st/stacktrfmt.c +64 -0
- data/vendor/sedna/kernel/common/tr_debug.cpp +112 -0
- data/vendor/sedna/kernel/common/tr_debug.h +22 -0
- data/vendor/sedna/kernel/common/u/Makefile +14 -0
- data/vendor/sedna/kernel/common/u/u.c +268 -0
- data/vendor/sedna/kernel/common/u/u.h +715 -0
- data/vendor/sedna/kernel/common/u/uatomic.h +12 -0
- data/vendor/sedna/kernel/common/u/udl.h +31 -0
- data/vendor/sedna/kernel/common/u/uevent.c +406 -0
- data/vendor/sedna/kernel/common/u/uevent.h +71 -0
- data/vendor/sedna/kernel/common/u/ugnames.cpp +330 -0
- data/vendor/sedna/kernel/common/u/ugnames.h +134 -0
- data/vendor/sedna/kernel/common/u/uhash_map.h +77 -0
- data/vendor/sedna/kernel/common/u/uhdd.c +1018 -0
- data/vendor/sedna/kernel/common/u/uhdd.h +206 -0
- data/vendor/sedna/kernel/common/u/ummap.cpp +268 -0
- data/vendor/sedna/kernel/common/u/ummap.h +60 -0
- data/vendor/sedna/kernel/common/u/umutex.c +145 -0
- data/vendor/sedna/kernel/common/u/umutex.h +65 -0
- data/vendor/sedna/kernel/common/u/upipe.cpp +244 -0
- data/vendor/sedna/kernel/common/u/upipe.h +74 -0
- data/vendor/sedna/kernel/common/u/uprocess.c +767 -0
- data/vendor/sedna/kernel/common/u/uprocess.h +91 -0
- data/vendor/sedna/kernel/common/u/usafesync.h +41 -0
- data/vendor/sedna/kernel/common/u/usecurity.c +150 -0
- data/vendor/sedna/kernel/common/u/usecurity.h +55 -0
- data/vendor/sedna/kernel/common/u/usem.c +891 -0
- data/vendor/sedna/kernel/common/u/usem.h +83 -0
- data/vendor/sedna/kernel/common/u/ushm.c +222 -0
- data/vendor/sedna/kernel/common/u/ushm.h +46 -0
- data/vendor/sedna/kernel/common/u/usocket.c +541 -0
- data/vendor/sedna/kernel/common/u/usocket.h +118 -0
- data/vendor/sedna/kernel/common/u/usystem.c +57 -0
- data/vendor/sedna/kernel/common/u/usystem.h +46 -0
- data/vendor/sedna/kernel/common/u/uthread.c +259 -0
- data/vendor/sedna/kernel/common/u/uthread.h +95 -0
- data/vendor/sedna/kernel/common/u/utime.c +65 -0
- data/vendor/sedna/kernel/common/u/utime.h +40 -0
- data/vendor/sedna/kernel/common/u/uutils.c +142 -0
- data/vendor/sedna/kernel/common/u/uutils.h +65 -0
- data/vendor/sedna/kernel/common/ugc.cpp +156 -0
- data/vendor/sedna/kernel/common/ugc.h +15 -0
- data/vendor/sedna/kernel/common/utils.cpp +156 -0
- data/vendor/sedna/kernel/common/utils.h +133 -0
- data/vendor/sedna/kernel/common/version.c +16 -0
- data/vendor/sedna/kernel/common/version.h +21 -0
- data/vendor/sedna/kernel/common/wustructures.h +18 -0
- data/vendor/sedna/kernel/common/wutypes.h +34 -0
- data/vendor/sedna/kernel/common/xptr.cpp +17 -0
- data/vendor/sedna/kernel/common/xptr.h +211 -0
- data/vendor/sedna/ver +1 -0
- metadata +142 -14
@@ -0,0 +1,338 @@
|
|
1
|
+
|
2
|
+
/* Win NT implementation of the stack trace library.
|
3
|
+
Note - Dbghelp library we are using internaly is single threaded.
|
4
|
+
We synchronise using the global mutex (hGlobalMutex). If waiting
|
5
|
+
on the mutex times out we assume deadlock and report failure. */
|
6
|
+
|
7
|
+
#include <windows.h>
|
8
|
+
#include <Dbghelp.h>
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <assert.h>
|
11
|
+
#include <stdarg.h>
|
12
|
+
#include <stddef.h>
|
13
|
+
#include "../stacktrace.h"
|
14
|
+
|
15
|
+
#define GLOBAL_MUTEX_TIMEOUT 1000
|
16
|
+
|
17
|
+
/* Conditionally defining STACK_GROWS_UPWARDS and STACK_GROWS_DOWNWARDS
|
18
|
+
boolean constants. "Upwards" means stack grows towards higher addresses
|
19
|
+
and "downwards" means stack grows towards lower addresses. */
|
20
|
+
#ifdef _X86_
|
21
|
+
#define STACK_GROWS_UPWARDS 0
|
22
|
+
#define STACK_GROWS_DOWNWARDS 1
|
23
|
+
#else
|
24
|
+
#error Stacktrace library doesn't support current processor architecture!
|
25
|
+
#endif
|
26
|
+
|
27
|
+
static int isInitialized = 0;
|
28
|
+
static HANDLE hGlobalMutex = NULL;
|
29
|
+
static const DWORD exceptCode = 'ECTX';
|
30
|
+
|
31
|
+
//
|
32
|
+
static DWORD InvokeProcWithContextExceptionFilter(LPEXCEPTION_POINTERS exceptionPointers,
|
33
|
+
int (*proc) (PCONTEXT pContext, void *params),
|
34
|
+
void *params,
|
35
|
+
int *status)
|
36
|
+
{
|
37
|
+
DWORD ret = EXCEPTION_CONTINUE_SEARCH;
|
38
|
+
|
39
|
+
if (exceptionPointers->ExceptionRecord->ExceptionCode == exceptCode)
|
40
|
+
{
|
41
|
+
ret = EXCEPTION_EXECUTE_HANDLER;
|
42
|
+
*status = proc(exceptionPointers->ContextRecord, params);
|
43
|
+
}
|
44
|
+
|
45
|
+
return ret;
|
46
|
+
}
|
47
|
+
//
|
48
|
+
static
|
49
|
+
int InvokeProcWithContext(int (*proc) (PCONTEXT pContext, void *params),
|
50
|
+
PCONTEXT pContext,
|
51
|
+
void *params)
|
52
|
+
{
|
53
|
+
int success = 0;
|
54
|
+
|
55
|
+
assert(proc);
|
56
|
+
if (pContext)
|
57
|
+
{
|
58
|
+
success = proc(pContext, params);
|
59
|
+
}
|
60
|
+
else
|
61
|
+
{
|
62
|
+
/* We raise an exception to capture current thread context
|
63
|
+
(using GetThreadContext for this purpose requires SuspendThread
|
64
|
+
and hence we must start an additional thread if we use GetThreadCtx solution).
|
65
|
+
Stack is analysed in the exception filter to ensure that
|
66
|
+
stack's top isn't overwritten so we can walk the stack
|
67
|
+
starting from the position encoded in the captured context.
|
68
|
+
|
69
|
+
TODO: what happens if an exception occurs during filter function
|
70
|
+
execution? */
|
71
|
+
__try { RaiseException(exceptCode, 0, 0, NULL); }
|
72
|
+
__except (InvokeProcWithContextExceptionFilter(
|
73
|
+
GetExceptionInformation(), proc, params, &success)) {}
|
74
|
+
}
|
75
|
+
return success;
|
76
|
+
}
|
77
|
+
//
|
78
|
+
typedef struct StackTraceWalkInternal2Params_tag_
|
79
|
+
{
|
80
|
+
StackTraceWalkProc walkProc;
|
81
|
+
void *userData;
|
82
|
+
int limit;
|
83
|
+
int offset;
|
84
|
+
void *marker;
|
85
|
+
}
|
86
|
+
StackTraceWalkInternal2Params;
|
87
|
+
//
|
88
|
+
static
|
89
|
+
int StackTraceWalkInternal2(PCONTEXT, void *);
|
90
|
+
//
|
91
|
+
static
|
92
|
+
int StackTraceWalkInternal(StackTraceWalkProc walkProc,
|
93
|
+
PCONTEXT pContext,
|
94
|
+
void *userData,
|
95
|
+
int limit,
|
96
|
+
int offset,
|
97
|
+
void *marker)
|
98
|
+
{
|
99
|
+
int success = 0;
|
100
|
+
StackTraceWalkInternal2Params params = { 0 };
|
101
|
+
|
102
|
+
assert(walkProc);
|
103
|
+
params.walkProc = walkProc;
|
104
|
+
params.userData = userData;
|
105
|
+
params.limit = limit;
|
106
|
+
params.offset = offset;
|
107
|
+
params.marker = marker;
|
108
|
+
|
109
|
+
if (!isInitialized)
|
110
|
+
{
|
111
|
+
/* library not initialized */
|
112
|
+
}
|
113
|
+
else if (WAIT_OBJECT_0 != WaitForSingleObject(hGlobalMutex, GLOBAL_MUTEX_TIMEOUT))
|
114
|
+
{
|
115
|
+
/* waiting for mutex fails for some reasons */
|
116
|
+
}
|
117
|
+
else
|
118
|
+
{
|
119
|
+
success = InvokeProcWithContext(StackTraceWalkInternal2, pContext, ¶ms);
|
120
|
+
ReleaseMutex(hGlobalMutex);
|
121
|
+
}
|
122
|
+
|
123
|
+
return success;
|
124
|
+
}
|
125
|
+
//
|
126
|
+
static DWORD2ADDRESS64(LPADDRESS64 a64, DWORD_PTR address)
|
127
|
+
{
|
128
|
+
assert(a64);
|
129
|
+
a64->Offset = address;
|
130
|
+
a64->Segment = 0;
|
131
|
+
a64->Mode = AddrModeFlat;
|
132
|
+
}
|
133
|
+
//
|
134
|
+
static DWORD_PTR ADDRESS64_2DWORD(LPADDRESS64 a64)
|
135
|
+
{
|
136
|
+
assert(a64);
|
137
|
+
return (DWORD_PTR)a64->Offset;
|
138
|
+
}
|
139
|
+
//
|
140
|
+
static
|
141
|
+
int StackTraceWalkInternal2(PCONTEXT pContext, void *paramsPtr)
|
142
|
+
{
|
143
|
+
int success = 0, bContinue = 1, frame = 0;
|
144
|
+
StackTraceWalkInternal2Params *params = (StackTraceWalkInternal2Params *)paramsPtr;
|
145
|
+
HANDLE hThread = NULL, hProcess = NULL;
|
146
|
+
STACKFRAME64 stackFrame = {0};
|
147
|
+
CONTEXT context = {0};
|
148
|
+
DWORD machineType = -1;
|
149
|
+
void *framep = NULL;
|
150
|
+
|
151
|
+
assert(pContext && params && params->walkProc);
|
152
|
+
context = *pContext;
|
153
|
+
hProcess = GetCurrentProcess();
|
154
|
+
hThread = GetCurrentThread();
|
155
|
+
|
156
|
+
#ifdef _X86_
|
157
|
+
machineType = IMAGE_FILE_MACHINE_I386;
|
158
|
+
DWORD2ADDRESS64(&stackFrame.AddrPC, context.Eip);
|
159
|
+
DWORD2ADDRESS64(&stackFrame.AddrFrame, context.Ebp);
|
160
|
+
DWORD2ADDRESS64(&stackFrame.AddrStack, context.Esp);
|
161
|
+
#else
|
162
|
+
#error 0
|
163
|
+
#endif
|
164
|
+
|
165
|
+
while (bContinue)
|
166
|
+
{
|
167
|
+
if (ADDRESS64_2DWORD(&stackFrame.AddrPC) == 0 ||
|
168
|
+
frame - params->offset >= params->limit)
|
169
|
+
{
|
170
|
+
/* the stack is over */
|
171
|
+
bContinue = 0;
|
172
|
+
success = 1;
|
173
|
+
}
|
174
|
+
else if (!StackWalk64(
|
175
|
+
machineType, hProcess, hThread, &stackFrame, &context,
|
176
|
+
NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
|
177
|
+
{
|
178
|
+
/* stack walk failed (why?) */
|
179
|
+
bContinue = 0;
|
180
|
+
success = 1; /* TODO: investigate how StackWalk reports of the stack end */
|
181
|
+
}
|
182
|
+
else if (framep = (void *) ADDRESS64_2DWORD(&stackFrame.AddrFrame),
|
183
|
+
params->marker != NULL &&
|
184
|
+
(STACK_GROWS_UPWARDS && params->marker < framep ||
|
185
|
+
STACK_GROWS_DOWNWARDS && params->marker > framep))
|
186
|
+
{
|
187
|
+
/* ignore frame */
|
188
|
+
}
|
189
|
+
else if (frame<params->offset)
|
190
|
+
{
|
191
|
+
/* skip frame */
|
192
|
+
++frame;
|
193
|
+
}
|
194
|
+
else
|
195
|
+
{
|
196
|
+
IMAGEHLP_MODULE64 moduleInfo = {0};
|
197
|
+
struct
|
198
|
+
{
|
199
|
+
IMAGEHLP_SYMBOL64 info;
|
200
|
+
char nameBuf[512];
|
201
|
+
}
|
202
|
+
symbolInfoEx = {0};
|
203
|
+
IMAGEHLP_LINE64 lineInfo = {0};
|
204
|
+
DWORD64 displ = 0;
|
205
|
+
StackFrameInfo frameInfo = {0};
|
206
|
+
|
207
|
+
moduleInfo.SizeOfStruct = sizeof moduleInfo;
|
208
|
+
if (SymGetModuleInfo64(hProcess, stackFrame.AddrPC.Offset, &moduleInfo))
|
209
|
+
{
|
210
|
+
frameInfo.module = moduleInfo.ImageName;
|
211
|
+
}
|
212
|
+
symbolInfoEx.info.SizeOfStruct = sizeof symbolInfoEx.info;
|
213
|
+
symbolInfoEx.info.MaxNameLength = sizeof symbolInfoEx.nameBuf;
|
214
|
+
if (SymGetSymFromAddr64(hProcess, stackFrame.AddrPC.Offset, &displ, &symbolInfoEx.info))
|
215
|
+
{
|
216
|
+
frameInfo.function = symbolInfoEx.info.Name;
|
217
|
+
}
|
218
|
+
lineInfo.SizeOfStruct = sizeof lineInfo;
|
219
|
+
if (SymGetLineFromAddr64(hProcess, stackFrame.AddrPC.Offset, (PDWORD)&displ, &lineInfo))
|
220
|
+
{
|
221
|
+
frameInfo.line = lineInfo.LineNumber;
|
222
|
+
frameInfo.file = lineInfo.FileName;
|
223
|
+
}
|
224
|
+
frameInfo.addr = (void*) ADDRESS64_2DWORD(&stackFrame.AddrPC);
|
225
|
+
|
226
|
+
if (!params->walkProc(frame-params->offset, &frameInfo, &bContinue, params->userData))
|
227
|
+
{
|
228
|
+
/* walk proc failed */
|
229
|
+
bContinue = 0;
|
230
|
+
}
|
231
|
+
else if (bContinue == 0)
|
232
|
+
{
|
233
|
+
/* walk proc requested end of walk */
|
234
|
+
success = 1;
|
235
|
+
}
|
236
|
+
++frame;
|
237
|
+
}
|
238
|
+
}
|
239
|
+
|
240
|
+
return success;
|
241
|
+
}
|
242
|
+
//
|
243
|
+
typedef struct StackTraceWriteFdWalkProcParams_tag_
|
244
|
+
{
|
245
|
+
HANDLE handle;
|
246
|
+
}
|
247
|
+
StackTraceWriteFdWalkProcParams;
|
248
|
+
//
|
249
|
+
static int StackTraceWriteFdWalkProc(int frame, const StackFrameInfo *frameInfo, int *continueWalk, void *userData)
|
250
|
+
{
|
251
|
+
DWORD dummy;
|
252
|
+
StackTraceWriteFdWalkProcParams *params = NULL;
|
253
|
+
char buf[0x1000];
|
254
|
+
int charsCnt = 0;
|
255
|
+
int success = 0;
|
256
|
+
|
257
|
+
assert(frameInfo && continueWalk && userData);
|
258
|
+
params = (StackTraceWriteFdWalkProcParams *)userData;
|
259
|
+
|
260
|
+
charsCnt = PrintStackFrameInfo(_snprintf, buf, sizeof buf, frame, frameInfo, 0);
|
261
|
+
if (charsCnt < 0)
|
262
|
+
{
|
263
|
+
/* output truncated */
|
264
|
+
static const char truncated[] = {'.','.','.','<','t','r','u','n','c','a','t','e','d','>','\n'};
|
265
|
+
const ptrdiff_t offset = (sizeof buf) - (sizeof truncated);
|
266
|
+
assert (offset>0);
|
267
|
+
memcpy(buf + offset, truncated, sizeof truncated);
|
268
|
+
charsCnt = (int)sizeof buf;
|
269
|
+
}
|
270
|
+
|
271
|
+
success = (WriteFile(params->handle, buf, charsCnt, &dummy, NULL));
|
272
|
+
|
273
|
+
return success;
|
274
|
+
}
|
275
|
+
//
|
276
|
+
__declspec(noinline)
|
277
|
+
int StackTraceWalk(void *context,
|
278
|
+
StackTraceWalkProc walkProc, void *userData,
|
279
|
+
int limit, int offset)
|
280
|
+
{
|
281
|
+
void *marker = NULL;
|
282
|
+
|
283
|
+
if (!context)
|
284
|
+
{
|
285
|
+
offset += 1; /* have to hide StackTraceWalk frame */
|
286
|
+
marker = ▮
|
287
|
+
}
|
288
|
+
return StackTraceWalkInternal(walkProc, (PCONTEXT)context, userData, limit, offset, marker);
|
289
|
+
}
|
290
|
+
//
|
291
|
+
__declspec(noinline)
|
292
|
+
int StackTraceWriteFd(void *context, intptr_t handle, int limit, int offset)
|
293
|
+
{
|
294
|
+
void *marker = NULL;
|
295
|
+
StackTraceWriteFdWalkProcParams params = { 0 };
|
296
|
+
|
297
|
+
params.handle = (HANDLE)handle;
|
298
|
+
if (!context)
|
299
|
+
{
|
300
|
+
offset += 1; /* have to hide StackTraceWriteFd frame */
|
301
|
+
marker = ▮
|
302
|
+
}
|
303
|
+
return StackTraceWalkInternal(StackTraceWriteFdWalkProc,
|
304
|
+
(PCONTEXT)context,
|
305
|
+
¶ms,
|
306
|
+
limit,
|
307
|
+
offset,
|
308
|
+
marker);
|
309
|
+
}
|
310
|
+
//
|
311
|
+
int StackTraceInit()
|
312
|
+
{
|
313
|
+
int success = 0;
|
314
|
+
if (!isInitialized &&
|
315
|
+
(hGlobalMutex = CreateMutex(NULL,FALSE,NULL)) &&
|
316
|
+
SymInitialize(GetCurrentProcess(), NULL, TRUE))
|
317
|
+
{
|
318
|
+
success = 1;
|
319
|
+
}
|
320
|
+
if (!success)
|
321
|
+
{
|
322
|
+
CloseHandle(hGlobalMutex);
|
323
|
+
hGlobalMutex = NULL;
|
324
|
+
}
|
325
|
+
if (!isInitialized) isInitialized = success;
|
326
|
+
return success;
|
327
|
+
}
|
328
|
+
//
|
329
|
+
void StackTraceDeinit()
|
330
|
+
{
|
331
|
+
if (isInitialized)
|
332
|
+
{
|
333
|
+
SymCleanup(GetCurrentProcess());
|
334
|
+
CloseHandle(hGlobalMutex);
|
335
|
+
isInitialized = 0;
|
336
|
+
}
|
337
|
+
hGlobalMutex = NULL;
|
338
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#ifdef _WIN32
|
2
|
+
#include <windows.h>
|
3
|
+
#else
|
4
|
+
#include <unistd.h>
|
5
|
+
#endif
|
6
|
+
|
7
|
+
/* Generic implementation assuming we are unable to examine stack traces. */
|
8
|
+
#include "../stacktrace.h"
|
9
|
+
|
10
|
+
int StackTraceInit()
|
11
|
+
{
|
12
|
+
return 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
void StackTraceDeinit()
|
16
|
+
{
|
17
|
+
;
|
18
|
+
}
|
19
|
+
|
20
|
+
int StackTraceWalk(void *context, StackTraceWalkProc walkerProc, void *userData,
|
21
|
+
int limit, int offset)
|
22
|
+
{
|
23
|
+
return 0;
|
24
|
+
}
|
25
|
+
|
26
|
+
int StackTraceWriteFd(void *context, intptr_t fd, int limit, int offset)
|
27
|
+
{
|
28
|
+
static const char errorMsg[] =
|
29
|
+
"<unable to produce stack trace - feature disabled>\n";
|
30
|
+
|
31
|
+
#ifdef _WIN32
|
32
|
+
DWORD dummy;
|
33
|
+
WriteFile((HANDLE)fd, errorMsg, sizeof(errorMsg) - 1, &dummy, NULL);
|
34
|
+
#else
|
35
|
+
write(fd, errorMsg, (sizeof errorMsg) - 1);
|
36
|
+
#endif
|
37
|
+
|
38
|
+
return 0;
|
39
|
+
}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
/* Writing stack traces, cross platform. */
|
2
|
+
|
3
|
+
#if (_MDC_VER > 1000)
|
4
|
+
#pragma once
|
5
|
+
#endif
|
6
|
+
|
7
|
+
#ifndef STACKTRACE_H_INCLUDED
|
8
|
+
#define STACKTRACE_H_INCLUDED
|
9
|
+
|
10
|
+
#ifndef EXTERNC
|
11
|
+
#ifndef __cplusplus
|
12
|
+
#define EXTERNC
|
13
|
+
#else
|
14
|
+
#define EXTERNC extern "C"
|
15
|
+
#endif
|
16
|
+
#endif
|
17
|
+
|
18
|
+
#include "stdint.h"
|
19
|
+
|
20
|
+
/* Init the library. Non-zero indicates success. */
|
21
|
+
EXTERNC int StackTraceInit();
|
22
|
+
|
23
|
+
/* Deinit library - safe (though redundant) to call even if init failed. */
|
24
|
+
EXTERNC void StackTraceDeinit();
|
25
|
+
|
26
|
+
/* Write stack trace to file identified by descriptor fd (handle on WIN).
|
27
|
+
If context is NULL the calling thread stack trace
|
28
|
+
is writen (except the StackTraceWriteFd frames). If context
|
29
|
+
non-NULL it must point to platform specific structure capturing
|
30
|
+
the thread context (CONTEXT on NT, ucontext_t on UNIX).
|
31
|
+
Non-zero indicates success.
|
32
|
+
If the library is not initialised the call will fail (but won't crash). */
|
33
|
+
EXTERNC int StackTraceWriteFd(void *context, intptr_t fd, int limit, int offset);
|
34
|
+
|
35
|
+
typedef struct StackFrameInfo_tag_
|
36
|
+
{
|
37
|
+
const char *function;
|
38
|
+
const char *module;
|
39
|
+
const char *file;
|
40
|
+
int line;
|
41
|
+
void *addr;
|
42
|
+
}
|
43
|
+
StackFrameInfo;
|
44
|
+
|
45
|
+
typedef int (*StackTraceWalkProc)(int frame, const StackFrameInfo *frameInfo, int *continueWalk, void *userData);
|
46
|
+
|
47
|
+
/* Walk the stack invoking walkProc for each frame on the stack.
|
48
|
+
If context is NULL the calling thread stack is examined
|
49
|
+
(except StackTraceWalk frames). If context
|
50
|
+
non-NULL it must point to platform specific structure capturing
|
51
|
+
the thread context (CONTEXT on NT, ucontext_t on UNIX).
|
52
|
+
Walk commences if either all frames were visited or the walkProc
|
53
|
+
resets continueWalk variable or the walkProc fails
|
54
|
+
(the walkProc indicates sucess with non-zero return value).
|
55
|
+
Non-zero indicates success (no error condition encountered - either
|
56
|
+
all frames visited or the walkProc intentionaly stops the walk).
|
57
|
+
If the library is not initialised the call will fail (but won't crash).*/
|
58
|
+
EXTERNC int StackTraceWalk(void *context,
|
59
|
+
StackTraceWalkProc walkProc, void *userData,
|
60
|
+
int limit, int offset);
|
61
|
+
|
62
|
+
typedef
|
63
|
+
int (*SnprintfLikeProc) (char *buf, size_t count, const char *fmt, ...);
|
64
|
+
|
65
|
+
EXTERNC
|
66
|
+
int PrintStackFrameInfo(SnprintfLikeProc proc,
|
67
|
+
char *buf,
|
68
|
+
size_t count,
|
69
|
+
int frame,
|
70
|
+
const StackFrameInfo *frameInfo,
|
71
|
+
int reserved);
|
72
|
+
#endif
|