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("-----------------------------------");
- }
- }
- }
- }
C#里面使用与java类似的方法,示例代码如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Diagnostics;
- namespace TestProjectCSharp
- {
- class CallStack
- {
- public static void printCallStack()
- {
- StackTrace ss = new StackTrace(true);
- String flName = ss.GetFrame(1).GetFileName();// GetMethod().DeclaringType;
- int lineNo = ss.GetFrame(1).GetFileLineNumber();
- String methodName = ss.GetFrame(1).GetMethod().Name;
- Console.WriteLine(flName+"---"+lineNo+"---"+methodName);
- }
- }
- }
c里面获取堆栈跟系统有关(主要是获取函数名称不一致,获取地址是一致的),
linux下使用backtrace和backtrace_symbols函数,示例代码如下:(编译方法:gcc -o funstack -rdynamic -ldl funstack.c)
- //funstack.c
- #define _GNU_SOURCE
- #include <memory.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <signal.h>
- #include <ucontext.h>
- #include <dlfcn.h>
- #include <execinfo.h>
- #if defined(REG_RIP)
- # define SIGSEGV_STACK_IA64
- # define REGFORMAT "%016lx"
- #elif defined(REG_EIP)
- # define SIGSEGV_STACK_X86
- # define REGFORMAT "%08x"
- #else
- # define SIGSEGV_STACK_GENERIC
- # define REGFORMAT "%x"
- #endif
- static void signal_segv(int signum, siginfo_t* info, void*ptr) {
- static const char *si_codes[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"};
- size_t i;
- ucontext_t *ucontext = (ucontext_t*)ptr;
- #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
- int f = 0;
- Dl_info dlinfo;
- void **bp = 0;
- void *ip = 0;
- #else
- void *bt[20];
- char **strings;
- size_t sz;
- #endif
- #if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
- # if defined(SIGSEGV_STACK_IA64)
- ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP];
- bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];
- # elif defined(SIGSEGV_STACK_X86)
- ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP];
- bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];
- # endif
- fprintf(stderr, "Stack trace:/n");
- while(bp && ip) {
- if(!dladdr(ip, &dlinfo))
- break;
- const char *symname = dlinfo.dli_sname;
- fprintf(stderr, "% 2d: %p %s+%u (%s)/n",
- ++f,
- ip,
- symname,
- (unsigned)(ip - dlinfo.dli_saddr),
- dlinfo.dli_fname);
- if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main"))
- break;
- ip = bp[1];
- bp = (void**)bp[0];
- }
- #else
- fprintf(stderr, "Stack trace (non-dedicated):/n");
- sz = backtrace(bt, 20);
- strings = backtrace_symbols(bt, sz);
- for(i = 0; i < sz; ++i)