现在的位置: 首页 > 综合 > 正文

各语言打印调用栈

2013年03月07日 ⁄ 综合 ⁄ 共 3644字 ⁄ 字号 评论关闭

java里面可以使用Throwable类来获取堆栈,示例代码如下:

  1. package name.xu;  
  2. public class CallStack {  
  3.     public static void printCallStatck() {  
  4.         Throwable ex = new Throwable();  
  5.         StackTraceElement[] stackElements = ex.getStackTrace();  
  6.         if (stackElements != null) {  
  7.             for (int i = 0; i < stackElements.length; i++) {  
  8.                 System.out.print(stackElements[i].getClassName()+"/t");  
  9.                 System.out.print(stackElements[i].getFileName()+"/t");  
  10.                 System.out.print(stackElements[i].getLineNumber()+"/t");  
  11.                 System.out.println(stackElements[i].getMethodName());  
  12.                 System.out.println("-----------------------------------");  
  13.             }  
  14.         }  
  15.     }  
  16.       
  17. }  

 

C#里面使用与java类似的方法,示例代码如下:

[c-sharp] view
plain
copy

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Diagnostics;  
  6. namespace TestProjectCSharp  
  7. {  
  8.     class CallStack  
  9.     {  
  10.         public static void printCallStack()  
  11.         {  
  12.             StackTrace ss = new StackTrace(true);  
  13.             String flName = ss.GetFrame(1).GetFileName();// GetMethod().DeclaringType;   
  14.             int lineNo = ss.GetFrame(1).GetFileLineNumber();  
  15.             String methodName = ss.GetFrame(1).GetMethod().Name;  
  16.             Console.WriteLine(flName+"---"+lineNo+"---"+methodName);  
  17.         }  
  18.     }  
  19. }  

 

 

c里面获取堆栈跟系统有关(主要是获取函数名称不一致,获取地址是一致的),

linux下使用backtrace和backtrace_symbols函数,示例代码如下:(编译方法:gcc -o funstack -rdynamic -ldl funstack.c)

  1. //funstack.c  
  2. #define _GNU_SOURCE  
  3. #include <memory.h>  
  4. #include <stdlib.h>  
  5. #include <stdio.h>  
  6. #include <signal.h>  
  7. #include <ucontext.h>  
  8. #include <dlfcn.h>  
  9. #include <execinfo.h>  
  10. #if defined(REG_RIP)  
  11. # define SIGSEGV_STACK_IA64  
  12. # define REGFORMAT "%016lx"  
  13. #elif defined(REG_EIP)  
  14. # define SIGSEGV_STACK_X86  
  15. # define REGFORMAT "%08x"  
  16. #else  
  17. # define SIGSEGV_STACK_GENERIC  
  18. # define REGFORMAT "%x"  
  19. #endif  
  20. static void signal_segv(int signum, siginfo_t* info, void*ptr) {  
  21.         static const char *si_codes[3] = {"""SEGV_MAPERR""SEGV_ACCERR"};  
  22.         size_t i;  
  23.         ucontext_t *ucontext = (ucontext_t*)ptr;  
  24. #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)  
  25.         int f = 0;  
  26.         Dl_info dlinfo;  
  27.         void **bp = 0;  
  28.         void *ip = 0;  
  29. #else  
  30.         void *bt[20];  
  31.         char **strings;  
  32.         size_t sz;  
  33. #endif  
  34. #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)  
  35. # if defined(SIGSEGV_STACK_IA64)  
  36.         ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP];  
  37.         bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];  
  38. # elif defined(SIGSEGV_STACK_X86)  
  39.         ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP];  
  40.         bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];  
  41. # endif  
  42.         fprintf(stderr, "Stack trace:/n");  
  43.         while(bp && ip) {  
  44.                 if(!dladdr(ip, &dlinfo))  
  45.                         break;  
  46.                 const char *symname = dlinfo.dli_sname;  
  47.                 fprintf(stderr, "% 2d: %p %s+%u (%s)/n",  
  48.                                 ++f,  
  49.                                 ip,  
  50.                                 symname,  
  51.                                 (unsigned)(ip - dlinfo.dli_saddr),  
  52.                                 dlinfo.dli_fname);  
  53.                 if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main"))  
  54.                         break;  
  55.                 ip = bp[1];  
  56.                 bp = (void**)bp[0];  
  57.         }  
  58. #else  
  59.         fprintf(stderr, "Stack trace (non-dedicated):/n");  
  60.         sz = backtrace(bt, 20);  
  61.         strings = backtrace_symbols(bt, sz);  
  62.         for(i = 0; i < sz; ++i)  

抱歉!评论已关闭.