打印调用堆栈
来源:互联网 发布:景甜的神秘力量 知乎 编辑:程序博客网 时间:2024/05/01 07:53
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.csdn.net/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.csdn.net/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.csdn.net/chief1985/article/details/4618492
- 打印调用堆栈
- 打印调用堆栈
- IOS打印调用堆栈
- 打印函数调用堆栈
- 打印调用堆栈
- 打印调用堆栈
- 打印调用堆栈
- 打印调用堆栈
- android打印调用堆栈
- IOS打印调用堆栈
- lua打印调用堆栈
- JavaScript 打印调用堆栈
- 打印函数调用堆栈
- IOS打印调用堆栈
- 打印 JavaScript 函数调用堆栈
- Code Fragment-打印调用堆栈。
- linux打印函数调用堆栈
- Linux下打印调用堆栈
- 基于Apache Mina的一个简单应用
- memmove与memcpy
- 杨辉三角的显示
- Inno Setup入门(十一)——完成安装后执行某些程序
- Java关于十进制转换成十六进制、n进制的解决方案
- 打印调用堆栈
- 在Android的Listview中显示多种视图
- Inno Setup入门(十)——操作注册表
- 虽说作业式的论文很难发散思想,但还好吧!
- Inno Setup入门(九)——修改安装过程中的文字显示
- 微软等数据结构+算法面试100题全部答案集锦
- QT中防止中文乱码
- Inno Setup入门(八)——有选择性的安装文件
- 主流报表制作工具之王者争夺战:功能大PK系列之背景图保存