java里面可以使用Throwable类来获取堆栈,示例代码如下:
package name.xu;
public class CallStack {
public static void printCallStatck() {
Throwable ex = new Throwable();
StackTraceElement[] stackElements = ex.getStackTrace();
if (stackElements != null) {
for (int i = 0; i < stackElements.length; i++) {
System.out.print(stackElements[i].getClassName()+"/t");
System.out.print(stackElements[i].getFileName()+"/t");
System.out.print(stackElements[i].getLineNumber()+"/t");
System.out.println(stackElements[i].getMethodName());
System.out.println("-----------------------------------");
}
}
}
}
windows下使用GetThreadContext ,StackWalk,SymGetOptions ,SymFunctionTableAccess,示例代码如下:
#include "SimpleSymbolEngine.h"
#include <windows.h>
#include <psapi.h>
#include <iostream>
#include <sstream>
#include <cstddef>
#include <dbghelp.h>
#pragma comment( lib, "dbghelp" )
static char const szRCSID[] = "$Id: SimpleSymbolEngine.cpp,v 1.4 2005/05/04 21:52:05 Eleanor Exp {1}quot;;
//////////////////////////////////////////////////////////////////////////////////////
// Singleton for the engine (SymInitialize doesn't support multiple calls)
SimpleSymbolEngine& SimpleSymbolEngine::instance()
{
static SimpleSymbolEngine theEngine;
return theEngine;
}
/////////////////////////////////////////////////////////////////////////////////////
SimpleSymbolEngine::SimpleSymbolEngine()
{
hProcess = GetCurrentProcess();
DWORD dwOpts = SymGetOptions();
dwOpts |= SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS;
SymSetOptions ( dwOpts );
::SymInitialize( hProcess, 0, true );
}
/////////////////////////////////////////////////////////////////////////////////////
SimpleSymbolEngine::~SimpleSymbolEngine()
{
::SymCleanup( hProcess );
}
/////////////////////////////////////////////////////////////////////////////////////
std::string SimpleSymbolEngine::addressToString( PVOID address )
{
std::ostringstream oss;
// First the raw address
oss << "0x" << address;
// Then any name for the symbol
struct tagSymInfo
{
IMAGEHLP_SYMBOL symInfo;
char nameBuffer[ 4 * 256 ];
} SymInfo = { { sizeof( IMAGEHLP_SYMBOL ) } };
IMAGEHLP_SYMBOL * pSym = &SymInfo.symInfo;
pSym->MaxNameLength = sizeof( SymInfo ) - offsetof( tagSymInfo, symInfo.Name );
DWORD dwDisplacement;
if ( SymGetSymFromAddr( hProcess, (DWORD)address, &dwDisplacement, pSym) )
{
oss << " " << pSym->Name;
if ( dwDisplacement != 0 )
oss << "+0x" << std::hex << dwDisplacement << std::dec;
}
// Finally any file/line number
IMAGEHLP_LINE lineInfo = { sizeof( IMAGEHLP_LINE ) };
if ( SymGetLineFromAddr( hProcess, (DWORD)address, &dwDisplacement, &lineInfo ) )
{
char const *pDelim = strrchr( lineInfo.FileName, '//' );
oss << " at " << ( pDelim ? pDelim + 1 : lineInfo.FileName ) << "(" << lineInfo.LineNumber << ")";
}
return oss.str();
}
/////////////////////////////////////////////////////////////////////////////////////
// StackTrace: try to trace the stack to the given output
void SimpleSymbolEngine::StackTrace( PCONTEXT pContext, std::ostream & os )
{
os << " Frame Code address/n";
STACKFRAME stackFrame = {0};
stackFrame.AddrPC.Offset = pContext->Eip;
stackFrame.AddrPC.Mode = AddrModeFlat;
stackFrame.AddrFrame.Offset = pContext->Ebp;
stackFrame.AddrFrame.Mode = AddrModeFlat;
stackFrame.AddrStack.Offset = pContext->Esp;
stackFrame.AddrStack.Mode = AddrModeFlat;
while ( ::StackWalk(
IMAGE_FILE_MACHINE_I386,
hProcess,
GetCurrentThread(), // this value doesn't matter much if previous one is a real handle
&stackFrame,
pContext,
NULL,
::SymFunctionTableAccess,
::SymGetModuleBase,
NULL ) )
{
os << " 0x" << (PVOID) stackFrame.AddrFrame.Offset << " " << addressToString( (PVOID)stackFrame.AddrPC.Offset ) << "/n";
}
os.flush();
}
完整的代码到http://www.howzatt.demon.co.uk/articles/SimpleSymbolEngine.zip下载。http://www.codeproject.com/KB/threads/StackWalker.aspx里面也有例子。
参考:
http://www.diybl.com/course/3_program/java/javashl/2008119/96739.html
http://topic.youkuaiyun.com/u/20090618/11/7c19832a-975e-4be6-987b-e61d789b31b5.html
http://bbs3.chinaunix.net/viewthread.php?tid=950357&extra=&page=2
http://www.codeproject.com/KB/threads/StackWalker.aspx
http://topic.youkuaiyun.com/u/20070515/21/fc3ebc11-b871-4761-90ae-3c6ddc7b4248.html
http://www.diybl.com/course/3_program/c++/cppjs/20090403/163752_2.html
http://accu.org/index.php/journals/276
http://blog.thepimp.net/archives/how-to-generate-backtraces-on-windows-without-compiler.html
http://blog.youkuaiyun.com/chief1985/article/details/4618492