11#if defined(BI_COMP_BORLANDC)
19# if !defined(USE_MEMCHECK)
37# if ((__GNUC__ != 3) || ((__GNUC_MINOR__ != 3) && (__GNUC_MINOR__ != 2)))
38#if !defined(_WINTRUST_) && !defined(WINTRUST_H)
46#if defined(BI_COMP_MSC)
48#pragma warning(disable:4091)
53#if defined(BI_COMP_MSC)
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";
81 static TModule& GetModule();
84 static LPVOID SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase);
85 static BOOL SymGetModuleInfo(HANDLE hProcess, DWORD dwAddr, PIMAGEHLP_MODULE ModuleInfo);
86 static BOOL SymLoadModule(HANDLE hProcess, HANDLE hFile, PSTR ImageName, PSTR ModuleName, DWORD BaseOfDll, DWORD SizeOfDll);
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);
89 static BOOL SymUnDName(PIMAGEHLP_SYMBOL sym, LPSTR UnDecName, DWORD UnDecNameLength);
90 static BOOL SymInitialize(HANDLE hProcess, LPSTR UserSearchPath, BOOL fInvadeProcess);
91 static DWORD SymGetOptions();
92 static DWORD SymSetOptions(DWORD SymOptions);
93 static BOOL StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME StackFrame,
94 LPVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
95 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
96 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
97 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress);
102TImageHelp::GetModule()
104 static TModule imgModule(imgHlpStr,
true,
true,
false);
108# if defined(BI_COMP_BORLANDC)
111LPVOID TImageHelp::SymFunctionTableAccess(HANDLE p1, DWORD p2)
113 static TModuleProc2<LPVOID, HANDLE, DWORD>
114 symFunctionTableAccess(GetModule(), SymFunctionTableAccessStr);
115 return symFunctionTableAccess(p1,p2);
118BOOL TImageHelp::SymGetModuleInfo(HANDLE p1, DWORD p2, PIMAGEHLP_MODULE p3)
120 static TModuleProc3<BOOL, HANDLE,DWORD,PIMAGEHLP_MODULE>
121 symGetModuleInfo(GetModule(), SymGetModuleInfoStr);
122 return symGetModuleInfo(p1,p2,p3);
125BOOL TImageHelp::SymLoadModule(HANDLE p1, HANDLE p2, PSTR p3,PSTR p4, DWORD p5,
128 static TModuleProc6<BOOL,HANDLE,HANDLE,PSTR,PSTR,DWORD, DWORD>
129 symLoadModule(GetModule(), SymLoadModuleStr);
130 return symLoadModule(p1,p2,p3,p4,p5,p6);
133BOOL TImageHelp::SymGetSymFromAddr(HANDLE p1, DWORD p2, PDWORD p3,
136 static TModuleProc4<BOOL,HANDLE,DWORD,PDWORD, PIMAGEHLP_SYMBOL>
137 symGetSymFromAddr(GetModule(), SymGetSymFromAddrStr);
138 return symGetSymFromAddr(p1,p2,p3,p4);
141DWORD TImageHelp::UnDecorateSymbolName(LPCSTR p1, LPSTR p2, DWORD p3, DWORD p4)
143 static TModuleProc4<DWORD,LPCSTR,LPSTR,DWORD,DWORD>
144 unDecorateSymbolName(GetModule(), UnDecorateSymbolNameStr);
145 return unDecorateSymbolName(p1,p2,p3,p4);
148BOOL TImageHelp::SymUnDName(PIMAGEHLP_SYMBOL p1, LPSTR p2, DWORD p3)
150 static TModuleProc3<BOOL,PIMAGEHLP_SYMBOL,LPSTR,DWORD>
151 symUnDName(GetModule(), SymUnDNameStr);
152 return symUnDName(p1,p2,p3);
155BOOL TImageHelp::SymInitialize(HANDLE p1, LPSTR p2, BOOL p3)
157 static TModuleProc3<BOOL,HANDLE,LPSTR,BOOL>
158 symInitialize(GetModule(), SymInitializeStr);
159 return symInitialize(p1,p2,p3);
162DWORD TImageHelp::SymGetOptions()
164 static TModuleProc0<DWORD>
165 symGetOptions(GetModule(), SymGetOptionsStr);
166 return symGetOptions();
169DWORD TImageHelp::SymSetOptions(DWORD p1)
171 static TModuleProc1<DWORD,DWORD>
172 symSetOptions(GetModule(), SymSetOptionsStr);
173 return symSetOptions(p1);
176BOOL TImageHelp::StackWalk(DWORD p1, HANDLE p2, HANDLE p3, LPSTACKFRAME p4,
177 LPVOID p5, PREAD_PROCESS_MEMORY_ROUTINE p6,
178 PFUNCTION_TABLE_ACCESS_ROUTINE p7,
179 PGET_MODULE_BASE_ROUTINE p8,
180 PTRANSLATE_ADDRESS_ROUTINE p9)
182 static TModuleProc9<BOOL,DWORD,HANDLE,HANDLE,LPSTACKFRAME,LPVOID,
183 PREAD_PROCESS_MEMORY_ROUTINE,PFUNCTION_TABLE_ACCESS_ROUTINE,
184 PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE>
185 stackWalk(GetModule(), StackWalkStr);
186 return stackWalk(p1,p2,p3,p4,p5,p6,p7,p8,p9);
196static LPVOID __stdcall FunctionTableAccess(HANDLE hProcess, DWORD dwPCAddress);
197static DWORD __stdcall GetModuleBase(HANDLE hProcess, DWORD dwReturnAddress);
200#define MODULE_NAME_LEN 64
201#define SYMBOL_NAME_LEN 128
203#if defined(_DEF_DECLARED)
205#define TRACE_STACK(m)\
207 if(__OwlDiagGroupDef.IsEnabled()){\
208 tostringstream out; out << m;\
209 __OwlDiagGroupDef.Trace(out.str().c_str(), 0, __FILE__, __LINE__);\
214 #define TRACE_STACK(m)
218struct OWL_SYMBOL_INFO{
227static LPVOID __stdcall FunctionTableAccess(HANDLE hProcess, DWORD dwPCAddress)
229 return TImageHelp::SymFunctionTableAccess(hProcess, dwPCAddress);
232static DWORD __stdcall GetModuleBase(HANDLE hProcess, DWORD dwReturnAddress)
234 IMAGEHLP_MODULE moduleInfo;
236 if (TImageHelp::SymGetModuleInfo(hProcess, dwReturnAddress, &moduleInfo))
237 return moduleInfo.BaseOfImage;
239 MEMORY_BASIC_INFORMATION memoryBasicInfo;
241 if (::VirtualQueryEx(hProcess, (LPVOID) dwReturnAddress,
242 &memoryBasicInfo,
sizeof(memoryBasicInfo))){
245 DWORD cch = GetModuleFileNameA((HINSTANCE)memoryBasicInfo.AllocationBase,
249 if(!TImageHelp::SymLoadModule(hProcess,NULL, ((cch) ? szFile : NULL),
250 NULL, (DWORD) memoryBasicInfo.AllocationBase, 0)){
253 return (DWORD) memoryBasicInfo.AllocationBase;
262static BOOL ResolveSymbol(HANDLE hProcess, DWORD dwAddress, OWL_SYMBOL_INFO& siSymbol)
266 siSymbol.dwAddress = dwAddress;
269 CHAR rgchSymbol[
sizeof(IMAGEHLP_SYMBOL) + 255];
274 CHAR szWithOffset[256];
278 memset(&siSymbol, 0,
sizeof(OWL_SYMBOL_INFO));
279 mi.SizeOfStruct =
sizeof(IMAGEHLP_MODULE);
281 if (!TImageHelp::SymGetModuleInfo(hProcess, dwAddress, &mi))
282 lstrcpyA(siSymbol.szModule,
"<no module>");
284 LPSTR pszModule = strchr(mi.ImageName,
'\\');
285 if (pszModule == NULL)
286 pszModule = mi.ImageName;
290 lstrcpynA(siSymbol.szModule, pszModule,
COUNTOF(siSymbol.szModule));
291 lstrcatA(siSymbol.szModule,
"! ");
296 u.sym.SizeOfStruct =
sizeof(IMAGEHLP_SYMBOL);
297 u.sym.Address = dwAddress;
298 u.sym.MaxNameLength = 255;
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),
304 UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS)){
307 else if (TImageHelp::SymUnDName(&u.sym, szUndec,
COUNTOF(szUndec))){
311 if(siSymbol.dwOffset != 0){
312 wsprintfA(szWithOffset,
"%s + %d bytes", pszSymbol, siSymbol.dwOffset);
313 pszSymbol = szWithOffset;
317 pszSymbol =
"<no symbol>";
321 pszSymbol =
"<EX: no symbol>";
322 siSymbol.dwOffset = dwAddress - mi.BaseOfImage;
325 lstrcpynA(siSymbol.szSymbol, pszSymbol,
COUNTOF(siSymbol.szSymbol));
332class __TTraceClipboardData{
334 __TTraceClipboardData(uint32 target);
335 ~__TTraceClipboardData();
336 void SendOut(LPCSTR pszData);
346__TTraceClipboardData::__TTraceClipboardData(
uint32 target)
355__TTraceClipboardData::~__TTraceClipboardData()
361 if(!OpenClipboard(NULL))
363 else if (!EmptyClipboard() || SetClipboardData(CF_TEXT, Memory) == NULL){
371void __TTraceClipboardData::SendOut(LPCSTR pszData)
374 if (pszData == NULL || (nLength = lstrlenA(pszData)) == 0)
384 OutputDebugStringA(pszData);
389 Memory = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, 1024);
397 LPSTR pstr = (LPSTR)GlobalLock(Memory);
399 lstrcpyA(pstr, pszData);
400 GlobalUnlock(Memory);
411 if ((Used + nLength + 1) >= Size){
414 if(Size > (1024L*1024L)){
419 HGLOBAL hMemory = GlobalReAlloc(Memory, Size, GMEM_MOVEABLE);
428 LPSTR pstr = (LPSTR) GlobalLock(Memory);
430 lstrcpyA(pstr + Used, pszData);
432 GlobalUnlock(Memory);
450 __TTraceClipboardData clipboardData(target);
452 clipboardData.SendOut(
"=== begin OwlDumpStack output ===\r\n");
455 HANDLE hProcess = ::GetCurrentProcess();
456 if (TImageHelp::SymInitialize(hProcess, NULL, FALSE)){
458 DWORD dw = TImageHelp::SymGetOptions();
459 dw &= ~SYMOPT_UNDNAME;
460 TImageHelp::SymSetOptions(dw);
462 HANDLE hThread = ::GetCurrentThread();
463 CONTEXT threadContext;
465 threadContext.ContextFlags = CONTEXT_FULL;
467 if (::GetThreadContext(hThread, &threadContext))
469 STACKFRAME stackFrame;
470 memset(&stackFrame, 0,
sizeof(stackFrame));
471 stackFrame.AddrPC.Mode = AddrModeFlat;
476 dwMachType = IMAGE_FILE_MACHINE_I386;
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)
486 dwMachType = IMAGE_FILE_MACHINE_R4000;
487 stackFrame.AddrPC. Offset = treadContext.Fir;
488#elif defined(_M_ALPHA)
490 dwMachType = IMAGE_FILE_MACHINE_ALPHA;
491 stackFrame.AddrPC.Offset = (
unsigned long) threadContext.Fir;
494 dwMachType = IMAGE_FILE_MACHINE_POWERPC;
495 stackFrame.AddrPC.Offset = threadContext.Iar;
497#error Unknown Target Machine
500 for (
int nFrame = 0; nFrame < 1024; nFrame++){
501 if (!TImageHelp::StackWalk(dwMachType, hProcess, hProcess,&stackFrame,
502 &threadContext, NULL,FunctionTableAccess, GetModuleBase, NULL)){
505 adwAddress.
AddAt(stackFrame.AddrPC.Offset, nFrame);
510 DWORD dw = GetLastError();
513 "OwlDumpStack Error: IMAGEHLP.DLL wasn't found. "
514 "GetLastError() returned 0x%8.8X\r\n", dw);
515 clipboardData.SendOut(sz);
520 int cAddresses = adwAddress.
Size();
521 for (nAddress = 0; nAddress < cAddresses; nAddress++){
522 OWL_SYMBOL_INFO info;
523 DWORD dwAddress = adwAddress[nAddress];
526 wsprintfA(sz,
"%8.8X: ", dwAddress);
527 clipboardData.SendOut(sz);
529 if (ResolveSymbol(hProcess, dwAddress, info)){
530 clipboardData.SendOut(info.szModule);
531 clipboardData.SendOut(info.szSymbol);
534 clipboardData.SendOut(
"symbol not found");
535 clipboardData.SendOut(
"\r\n");
538 clipboardData.SendOut(
"=== end OwlDumpStack() output ===\r\n");
541# if defined(BI_COMP_BORLANDC)
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
void AddAt(R t, uint index)
Definition of container classes used and made available by OWL.
#define MODULE_NAME_LEN
defined(UNIX)
#define OWL_STACK_DUMP_TARGET_CLIPBOARD
#define OWL_STACK_DUMP_TARGET_TRACE
#define OWL_STACK_DUMP_TARGET_ODS
Definition of class TModule.
Object Windows Library (OWLNext Core).
void OwlDumpStack(uint32 target=OWL_STACK_DUMP_TARGET_DEFAULT)
TTypedArray< uint32, uint32, TStandardAllocator > TUint32Array
#define COUNTOF(s)
Array element count Important: Only use this with an argument of array type.
Definition of container classes used and made available by OWL.