OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
dumpstack.cpp
Go to the documentation of this file.
1//--------------------------------------------------------------------------
2// ObjectWindows //
3// Copyright (c) 1993, 1996 by Borland International
4// All Rights Reserved.
5// Copyright (c) 1998 by Yura Bidus //
6// //
7//------------------------------------------------------------------------//
8
9#include <owl/pch.h>
10
11#if defined(BI_COMP_BORLANDC)
12# pragma hdrstop
13#endif
14
15#if __DEBUG == 2
16# define USE_MEMCHECK
17#endif
18#ifdef _DEBUG
19# if !defined(USE_MEMCHECK)
20# define USE_MEMCHECK
21# endif
22#endif
23
24
26
27#include <owl/module.h>
28#include <owl/template.h>
29#include <owl/contain.h>
30
31namespace owl {
32
33using namespace std;
34
35//-----------------------------------------------------------------------------
36
37# if ((__GNUC__ != 3) || ((__GNUC_MINOR__ != 3) && (__GNUC_MINOR__ != 2)))
38#if !defined(_WINTRUST_) && !defined(WINTRUST_H)
39# include <wintrust.h>
40# endif // !defined(_WINTRUST_) && !defined(WINTRUST_H)
41# endif // ((__GNUC__ != 3) || ((__GNUC_MINOR__ != 3) && (__GNUC_MINOR__ != 2)))
42
43//
44// Disable warnings in header "imagehlp.h".
45//
46#if defined(BI_COMP_MSC)
47#pragma warning(push)
48#pragma warning(disable:4091) // warning C4091: 'typedef ': ignored on left of '' when no variable is declared
49#endif
50
51#include <imagehlp.h>
52
53#if defined(BI_COMP_MSC)
54#pragma warning(pop)
55#endif
56
57//#pragma comment(lib, "imagehlp.lib")
58
59static const tchar imgHlpStr[] = _T("imagehlp.dll");
60static const char SymFunctionTableAccessStr[] = "SymFunctionTableAccess";
61static const char SymGetModuleInfoStr[] = "SymGetModuleInfo";
62static const char SymLoadModuleStr[] = "SymLoadModule";
63static const char SymGetSymFromAddrStr[] = "SymGetSymFromAddr";
64static const char UnDecorateSymbolNameStr[] = "UnDecorateSymbolName";
65static const char SymUnDNameStr[] = "SymUnDName";
66static const char SymInitializeStr[] = "SymInitialize";
67static const char SymGetOptionsStr[] = "SymGetOptions";
68static const char SymSetOptionsStr[] = "SymSetOptions";
69static const char StackWalkStr[] = "StackWalk";
70//static const char Str[] = "";
71//static const char Str[] = "";
72//static const char Str[] = "";
73
74//-----------------------------------------------------------------------------
75// class IMAGEHLP
76// ~~~~~ ~~~~~~~~
77//
78// delay loading IMAGEHLP.DLL
79class TImageHelp {
80 public:
81 static TModule& GetModule();
82
83 // Environmental
84 static LPVOID SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase);
85 static BOOL SymGetModuleInfo(HANDLE hProcess, DWORD dwAddr, PIMAGEHLP_MODULE ModuleInfo);
87 static BOOL SymGetSymFromAddr(HANDLE hProcess, DWORD dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_SYMBOL Symbol);
88 static DWORD UnDecorateSymbolName(LPCSTR DecoratedName, LPSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags);
91 static DWORD SymGetOptions();
92 static DWORD SymSetOptions(DWORD SymOptions);
98
99};
100//-----------------------------------------------------------------------------
101TModule&
102TImageHelp::GetModule()
103{
104 static TModule imgModule(imgHlpStr, true, true, false);
105 return imgModule;
106}
107//-----------------------------------------------------------------------------
108# if defined(BI_COMP_BORLANDC)
109# pragma warn -inl
110# endif
111LPVOID TImageHelp::SymFunctionTableAccess(HANDLE p1, DWORD p2)
112{
114 symFunctionTableAccess(GetModule(), SymFunctionTableAccessStr);
116}
117//-----------------------------------------------------------------------------
118BOOL TImageHelp::SymGetModuleInfo(HANDLE p1, DWORD p2, PIMAGEHLP_MODULE p3)
119{
121 symGetModuleInfo(GetModule(), SymGetModuleInfoStr);
122 return symGetModuleInfo(p1,p2,p3);
123}
124//-----------------------------------------------------------------------------
125BOOL TImageHelp::SymLoadModule(HANDLE p1, HANDLE p2, PSTR p3,PSTR p4, DWORD p5,
126 DWORD p6)
127{
129 symLoadModule(GetModule(), SymLoadModuleStr);
130 return symLoadModule(p1,p2,p3,p4,p5,p6);
131}
132//-----------------------------------------------------------------------------
133BOOL TImageHelp::SymGetSymFromAddr(HANDLE p1, DWORD p2, PDWORD p3,
135{
137 symGetSymFromAddr(GetModule(), SymGetSymFromAddrStr);
138 return symGetSymFromAddr(p1,p2,p3,p4);
139}
140//-----------------------------------------------------------------------------
141DWORD TImageHelp::UnDecorateSymbolName(LPCSTR p1, LPSTR p2, DWORD p3, DWORD p4)
142{
144 unDecorateSymbolName(GetModule(), UnDecorateSymbolNameStr);
146}
147//-----------------------------------------------------------------------------
148BOOL TImageHelp::SymUnDName(PIMAGEHLP_SYMBOL p1, LPSTR p2, DWORD p3)
149{
151 symUnDName(GetModule(), SymUnDNameStr);
152 return symUnDName(p1,p2,p3);
153}
154//-----------------------------------------------------------------------------
155BOOL TImageHelp::SymInitialize(HANDLE p1, LPSTR p2, BOOL p3)
156{
158 symInitialize(GetModule(), SymInitializeStr);
159 return symInitialize(p1,p2,p3);
160}
161//-----------------------------------------------------------------------------
162DWORD TImageHelp::SymGetOptions()
163{
165 symGetOptions(GetModule(), SymGetOptionsStr);
166 return symGetOptions();
167}
168//-----------------------------------------------------------------------------
169DWORD TImageHelp::SymSetOptions(DWORD p1)
170{
172 symSetOptions(GetModule(), SymSetOptionsStr);
173 return symSetOptions(p1);
174}
175//-----------------------------------------------------------------------------
176BOOL TImageHelp::StackWalk(DWORD p1, HANDLE p2, HANDLE p3, LPSTACKFRAME p4,
181{
185 stackWalk(GetModule(), StackWalkStr);
186 return stackWalk(p1,p2,p3,p4,p5,p6,p7,p8,p9);
187}
188//-----------------------------------------------------------------------------
189//-----------------------------------------------------------------------------
190//-----------------------------------------------------------------------------
191//-----------------------------------------------------------------------------
192//-----------------------------------------------------------------------------
193/////////////////////////////////////////////////////////////////////////////
194// Routine to produce stack dump
195#if !defined(UNIX) //JJH we do not need this stuff in unix
196static LPVOID __stdcall FunctionTableAccess(HANDLE hProcess, DWORD dwPCAddress);
197static DWORD __stdcall GetModuleBase(HANDLE hProcess, DWORD dwReturnAddress);
198#endif ///defined(UNIX)
199
200#define MODULE_NAME_LEN 64
201#define SYMBOL_NAME_LEN 128
202
203#if defined(_DEF_DECLARED)
204
205#define TRACE_STACK(m)\
206 do{\
207 if(__OwlDiagGroupDef.IsEnabled()){\
208 tostringstream out; out << m;\
209 __OwlDiagGroupDef.Trace(out.str().c_str(), 0, __FILE__, __LINE__);\
210 }\
211 }while(0)
212
213#else //no _DEF_DECLARED
214 #define TRACE_STACK(m)
215#endif //_DEF_DECLARED
216
217/// \cond
218struct OWL_SYMBOL_INFO{
223};
224/// \endcond
225
226#if !defined(UNIX) //JJH see OwlDumpStack below...
227static LPVOID __stdcall FunctionTableAccess(HANDLE hProcess, DWORD dwPCAddress)
228{
229 return TImageHelp::SymFunctionTableAccess(hProcess, dwPCAddress);
230}
231
232static DWORD __stdcall GetModuleBase(HANDLE hProcess, DWORD dwReturnAddress)
233{
235
236 if (TImageHelp::SymGetModuleInfo(hProcess, dwReturnAddress, &moduleInfo))
237 return moduleInfo.BaseOfImage;
238 else{
240
243
244 char szFile[MAX_PATH] = { 0 };
247
248 // Ignore the return code since we can't do anything with it.
249 if(!TImageHelp::SymLoadModule(hProcess,NULL, ((cch) ? szFile : NULL),
251 TRACE_STACK(_T("Error: ") << GetLastError());
252 }
253 return (DWORD) memoryBasicInfo.AllocationBase;
254 }
255 else{
256 TRACE_STACK(_T("Error is ") << GetLastError());
257 }
258 }
259 return 0;
260}
261
263{
264 BOOL fRetval = TRUE;
265
266 siSymbol.dwAddress = dwAddress;
267
268 union __SYMB{
269 CHAR rgchSymbol[sizeof(IMAGEHLP_SYMBOL) + 255];
271 } u;
272
273 CHAR szUndec[256];
274 CHAR szWithOffset[256];
277
278 memset(&siSymbol, 0, sizeof(OWL_SYMBOL_INFO));
279 mi.SizeOfStruct = sizeof(IMAGEHLP_MODULE);
280
281 if (!TImageHelp::SymGetModuleInfo(hProcess, dwAddress, &mi))
282 lstrcpyA(siSymbol.szModule, "<no module>");
283 else{
284 LPSTR pszModule = strchr(mi.ImageName, '\\');
285 if (pszModule == NULL)
286 pszModule = mi.ImageName;
287 else
288 pszModule++;
289
290 lstrcpynA(siSymbol.szModule, pszModule, COUNTOF(siSymbol.szModule));
291 lstrcatA(siSymbol.szModule, "! ");
292 }
293
294 __try
295 {
296 u.sym.SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
297 u.sym.Address = dwAddress;
298 u.sym.MaxNameLength = 255;
299
300 if (TImageHelp::SymGetSymFromAddr(hProcess, dwAddress,
301 &(siSymbol.dwOffset), &u.sym)){
302 pszSymbol = u.sym.Name;
303 if (TImageHelp::UnDecorateSymbolName(u.sym.Name, szUndec, COUNTOF(szUndec),
306 }
307 else if (TImageHelp::SymUnDName(&u.sym, szUndec, COUNTOF(szUndec))){
309 }
310
311 if(siSymbol.dwOffset != 0){
312 wsprintfA(szWithOffset, "%s + %d bytes", pszSymbol, siSymbol.dwOffset);
314 }
315 }
316 else
317 pszSymbol = "<no symbol>";
318 }
319 __except(true)
320 {
321 pszSymbol = "<EX: no symbol>";
322 siSymbol.dwOffset = dwAddress - mi.BaseOfImage;
323 }
324
325 lstrcpynA(siSymbol.szSymbol, pszSymbol, COUNTOF(siSymbol.szSymbol));
326 return fRetval;
327}
328
329#endif //if !defined(UNIX)
330
331/// \cond
333 public:
336 void SendOut(LPCSTR pszData);
337 private:
339 uint32 Size;
340 uint32 Used;
341 uint32 Target;
342
343};
344/// \endcond
345
346__TTraceClipboardData::__TTraceClipboardData(uint32 target)
347:
348 Memory(0)
349 ,Size(0)
350 ,Used(0)
351 ,Target(target)
352{
353}
354
355__TTraceClipboardData::~__TTraceClipboardData()
356{
357 if (Memory){
358 // chuck it onto the clipboard
359 // don't free it unless there's an error
360
361 if(!OpenClipboard(NULL))
363 else if (!EmptyClipboard() || SetClipboardData(CF_TEXT, Memory) == NULL){
365 }
366 else
367 CloseClipboard();
368 }
369}
370
371void __TTraceClipboardData::SendOut(LPCSTR pszData)
372{
373 int nLength;
374 if (pszData == NULL || (nLength = lstrlenA(pszData)) == 0)
375 return;
376
377 // send it to TRACE (can be redirected)
378 if (Target & OWL_STACK_DUMP_TARGET_TRACE){
380 }
381
382 // send it to OutputDebugString() (can't redirect)
383 if (Target & OWL_STACK_DUMP_TARGET_ODS)
385
386 // build a buffer for the clipboard
388 if(!Memory){
390 if(!Memory){
391 //TRACE("OwlDumpStack Error: No memory available for clipboard");
392 Target &= ~OWL_STACK_DUMP_TARGET_CLIPBOARD;
393 }
394 else{
395 Used = nLength;
396 Size = 1024;
398 if (pstr){
401 }
402 else{
403 //TRACE("OwlDumpStack Error: Couldn't lock memory!");
405 Memory = 0;
406 Target &= ~OWL_STACK_DUMP_TARGET_CLIPBOARD;
407 }
408 }
409 }
410 else{
411 if ((Used + nLength + 1) >= Size){
412 // grow by leaps and bounds
413 Size *= 2;
414 if(Size > (1024L*1024L)){
415 //TRACE("OwlDumpStack Error: more than one megabyte on clipboard.");
416 Target &= ~OWL_STACK_DUMP_TARGET_CLIPBOARD;
417 }
418
420 if (!hMemory){
421 //TRACE(_T("OwlDumpStack Error: Couldn't get ") << Size << _T("bytes!"));
422 Target &= ~OWL_STACK_DUMP_TARGET_CLIPBOARD;
423 }
424 else
425 Memory = hMemory;
426 }
427
429 if (pstr){
431 Used += nLength;
433 }
434 else{
435 //TRACE("OwlDumpStack Error: Couldn't lock memory!");
436 Target &= ~OWL_STACK_DUMP_TARGET_CLIPBOARD;
437 }
438 }
439 }
440 return;
441}
442
443/////////////////////////////////////////////////////////////////////////////
444// OwlDumpStack API
445_OWLFUNC(void)
446OwlDumpStack(uint32 target /* = OWL_STACK_DUMP_TARGET_DEFAULT */)
447{
448#if !defined(UNIX)
449
451
452 clipboardData.SendOut("=== begin OwlDumpStack output ===\r\n");
453
456 if (TImageHelp::SymInitialize(hProcess, NULL, FALSE)){
457 // force undecorated names to get params
458 DWORD dw = TImageHelp::SymGetOptions();
460 TImageHelp::SymSetOptions(dw);
461
464
465 threadContext.ContextFlags = CONTEXT_FULL;
466
468 {
470 memset(&stackFrame, 0, sizeof(stackFrame));
471 stackFrame.AddrPC.Mode = AddrModeFlat;
472
474
475#if defined(_M_IX86)
477
478 // program counter, stack pointer, and frame pointer
479 stackFrame.AddrPC.Offset = threadContext.Eip;
480 stackFrame.AddrStack.Offset = threadContext.Esp;
481 stackFrame.AddrStack.Mode = AddrModeFlat;
482 stackFrame.AddrFrame.Offset = threadContext.Ebp;
483 stackFrame.AddrFrame.Mode = AddrModeFlat;
484#elif defined(_M_MRX000)
485 // only program counter
487 stackFrame.AddrPC. Offset = treadContext.Fir;
488#elif defined(_M_ALPHA)
489 // only program counter
491 stackFrame.AddrPC.Offset = (unsigned long) threadContext.Fir;
492#elif defined(_M_PPC)
493 // only program counter
495 stackFrame.AddrPC.Offset = threadContext.Iar;
496#else
497#error Unknown Target Machine
498#endif
499
500 for (int nFrame = 0; nFrame < 1024; nFrame++){
501 if (!TImageHelp::StackWalk(dwMachType, hProcess, hProcess,&stackFrame,
502 &threadContext, NULL,FunctionTableAccess, GetModuleBase, NULL)){
503 break;
504 }
505 adwAddress.AddAt(stackFrame.AddrPC.Offset, nFrame);
506 }
507 }
508 }
509 else{
510 DWORD dw = GetLastError();
511 char sz[100];
513 "OwlDumpStack Error: IMAGEHLP.DLL wasn't found. "
514 "GetLastError() returned 0x%8.8X\r\n", dw);
515 clipboardData.SendOut(sz);
516 }
517
518 // dump it out now
519 int nAddress;
520 int cAddresses = adwAddress.Size();
521 for (nAddress = 0; nAddress < cAddresses; nAddress++){
524
525 char sz[20];
526 wsprintfA(sz, "%8.8X: ", dwAddress);
527 clipboardData.SendOut(sz);
528
529 if (ResolveSymbol(hProcess, dwAddress, info)){
530 clipboardData.SendOut(info.szModule);
531 clipboardData.SendOut(info.szSymbol);
532 }
533 else
534 clipboardData.SendOut("symbol not found");
535 clipboardData.SendOut("\r\n");
536 }
537
538 clipboardData.SendOut("=== end OwlDumpStack() output ===\r\n");
539#endif //(ifdef UNIX)
540}
541# if defined(BI_COMP_BORLANDC)
542# pragma warn .inl
543# endif
544
545
546} // OWL namespace
547/* ========================================================================== */
548
Definition of container classes used and made available by OWL.
#define MAX_PATH
Definition cygwin.h:98
#define _T(x)
Definition cygwin.h:51
#define SYMBOL_NAME_LEN
#define TRACE_STACK(m)
#define MODULE_NAME_LEN
defined(UNIX)
#define OWL_STACK_DUMP_TARGET_CLIPBOARD
Definition dumpstack.h:20
#define OWL_STACK_DUMP_TARGET_TRACE
Definition dumpstack.h:19
#define OWL_STACK_DUMP_TARGET_ODS
Definition dumpstack.h:22
Definition of class TModule.
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
unsigned long uint32
Definition number.h:34
char tchar
Definition defs.h:77
#define _OWLFUNC(p)
Definition defs.h:341
#define COUNTOF(s)
Array element count Important: Only use this with an argument of array type.
Definition defs.h:376
Definition of container classes used and made available by OWL.
#define __try
Definition unixxcpt.cpp:142
#define __except
Definition unixxcpt.cpp:144