c语音中打印参数调用层级即call stack, call trace
http://stackoverflow.com/questions/105659/how-can-one-grab-a-stack-trace-in-c
There's backtrace(), and backtrace_symbols():
From the man page:
#include <execinfo.h>
#include <stdio.h>
...
void* callstack[];
int i, frames = backtrace(callstack, );
char** strs = backtrace_symbols(callstack, frames);
for (i = ; i < frames; ++i) {
printf("%s\n", strs[i]);
}
free(strs);
...
One way to use this in a more convenient/OOP way is to save the result of backtrace_symbols() in an exception class constructor. Thus, whenever you throw that type of exception you have the stack trace. Then, just provide a function for printing it out. For example:
class MyException : public std::exception {
    char ** strs;
    MyException( const std::string & message ) {
         int i, frames = backtrace(callstack, );
         strs = backtrace_symbols(callstack, frames);
    }
    void printStackTrace() {
        for (i = ; i
      ......
try {
   throw MyException("Oops!");
} catch ( MyException e ) {
    e.printStackTrace();
}
提示,最好把编译优化去掉,不然打印可能不准确。
http://www.gnu.org/software/libc/manual/html_node/Backtraces.html
A backtrace is a list of the function calls that are currently active in a thread. The usual way to inspect a backtrace of a program is to use an external debugger such as gdb. However, sometimes it is useful to obtain a backtrace programmatically from within a program, e.g., for the purposes of logging or diagnostics.
The header fileexecinfo.hdeclares three functions that obtain and manipulate backtraces of the current thread.
- Function: int backtrace (void **buffer, int size)
- 
Preliminary: | MT-Safe | AS-Unsafe init heap dlopen plugin lock | AC-Unsafe init mem lock fd | See POSIX Safety Concepts. The backtracefunction obtains a backtrace for the current thread, as a list of pointers, and places the information into buffer. The argument size should be the number ofvoid *elements that will fit into buffer. The return value is the actual number of entries of buffer that are obtained, and is at most size.The pointers placed in buffer are actually return addresses obtained by inspecting the stack, one return address per stack frame. Note that certain compiler optimizations may interfere with obtaining a valid backtrace. Function inlining causes the inlined function to not have a stack frame; tail call optimization replaces one stack frame with another; frame pointer elimination will stop backtracefrom interpreting the stack contents correctly.
- Function: char ** backtrace_symbols (void *const *buffer, int size)
- 
Preliminary: | MT-Safe | AS-Unsafe heap | AC-Unsafe mem lock | See POSIX Safety Concepts. The backtrace_symbolsfunction translates the information obtained from thebacktracefunction into an array of strings. The argument buffer should be a pointer to an array of addresses obtained via thebacktracefunction, and size is the number of entries in that array (the return value ofbacktrace).The return value is a pointer to an array of strings, which has size entries just like the array buffer. Each string contains a printable representation of the corresponding element of buffer. It includes the function name (if this can be determined), an offset into the function, and the actual return address (in hexadecimal). Currently, the function name and offset only be obtained on systems that use the ELF binary format for programs and libraries. On other systems, only the hexadecimal return address will be present. Also, you may need to pass additional flags to the linker to make the function names available to the program. (For example, on systems using GNU ld, you must pass ( -rdynamic.)The return value of backtrace_symbolsis a pointer obtained via themallocfunction, and it is the responsibility of the caller tofreethat pointer. Note that only the return value need be freed, not the individual strings.The return value is NULLif sufficient memory for the strings cannot be obtained.
- Function: void backtrace_symbols_fd (void *const *buffer, int size, int fd)
- 
Preliminary: | MT-Safe | AS-Safe | AC-Unsafe lock | See POSIX Safety Concepts. The backtrace_symbols_fdfunction performs the same translation as the functionbacktrace_symbolsfunction. Instead of returning the strings to the caller, it writes the strings to the file descriptor fd, one per line. It does not use themallocfunction, and can therefore be used in situations where that function might fail.
The following program illustrates the use of these functions. Note that the array to contain the return addresses returned by backtrace is allocated on the stack. Therefore code like this can be used in situations where the memory handling via malloc does not work anymore (in which case the backtrace_symbols has to be replaced by a backtrace_symbols_fd call as well). The number of return addresses is normally not very large. Even complicated programs rather seldom have a nesting level of more than, say, 50 and with 200 possible entries probably all programs should be covered.
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h> /* Obtain a backtrace and print it to stdout. */
void
print_trace (void)
{
void *array[];
size_t size;
char **strings;
size_t i; size = backtrace (array, );
strings = backtrace_symbols (array, size); printf ("Obtained %zd stack frames.\n", size); for (i = ; i < size; i++)
printf ("%s\n", strings[i]); free (strings);
} /* A dummy function to make the backtrace more interesting. */
void
dummy_function (void)
{
print_trace ();
} int
main (void)
{
dummy_function ();
return ;
}
c语音中打印参数调用层级即call stack, call trace的更多相关文章
- JAVA学习笔记--方法中的参数调用是引用调用or值调用
		文献来源:<JAVA核心技术卷Ⅰ>,第4章第5节 (没有相关书籍的可看传送门) ps:测试demo因为偷懒,用的是String对象 结论:Java使用的是对象的值引用.即将任何对象所在内存 ... 
- unity 如何在botton AddListen中传递参数调用函数
		使用Deleget方法包含该函数即可. levelItem.GetComponent<Toggle().onValueChanged.AddListener(SetSelectedLevel(l ... 
- 描述了say_hello函数的具体内容,调用zend_printf系统函数在php中打印字符串
		下载一个php的源代码包,这里使用的是php 4.0.5版,解压后会看到php的根目录下会有README.EXT_SKEL这样一个文件,打开详细阅读了一下,发现了一个非常好用的工具,这个工具可以帮你构 ... 
- Liferay中SQL打印参数
		XX\tomcat-7.0.42\webapps\ROOT\WEB-INF\classes\log4j.properties log4j.rootLogger=INFO, CONSOLE log4 ... 
- 程序中打印当前进程的调用堆栈(backtrace)
		为了方便调式程序,产品中需要在程序崩溃或遇到问题时打印出当前的调用堆栈.由于是基于Linux的ARM嵌入式系统,没有足够的空间来存放coredump文件. 实现方法,首先用__builtin_fram ... 
- 在go中通过cmd调用python命令行参数量级过大问题解决
		问题描述如下: 在go中使用cmd调用python命令行 cmd := exec.Command("python", "dimine/Kriging/matrix.py& ... 
- Tom_No_02 Servlet向流中打印内容,之后在调用finsihResponse,调用上是先发送了body,后发送Header的解释
		上次在培训班学上网课的时候就发现了这个问题,一直没有解决,昨天又碰到了,2-3小时也未能发现点端倪,今早又仔细缕了下,让我看了他的秘密 1.Servlet向流中打印内容,之后在调用finsihResp ... 
- vlc 详细使用方法:libvlc_media_add_option 函数中的参数设置
		vlc 详细使用方法:libvlc_media_add_option 函数中的参数设置 [转载自]tinyle的专栏 [原文链接地址]http://blog.csdn.net/myaccella/ar ... 
- UIViewController中各方法调用顺序及功能详解
		UIViewController中各方法调用顺序及功能详解 UIViewController中loadView, viewDidLoad, viewWillUnload, viewDidUnload, ... 
随机推荐
- CentOS7修改网卡为eth0
			CentOS7修改网卡为eth0 1.编辑网卡信息 [root@linux-node2~]# cd /etc/sysconfig/network-scripts/ #进入网卡目录 [root@lin ... 
- qwt6在Windows下Qt5的编译,安装,初步使用
			今晚把qwt的编译,安装,初级使用放上来,以便需要的人,能更快部署好编程环境,不至于每次都像我这样花很多时间. 注意:Qtcreater使用的是什么编译器编译出来的,就要用那个编译器来编译qwt. 我 ... 
- 再看JavaScript线程
			继上篇讨论了一些关于JavaScript线程的知识,我们不妨回过头再看看,是不是JavaScript就不能多线程呢?看下面一段很简单的代码(演示用,没考虑兼容问题): 代码判断一: <div i ... 
- jquery禁用a标签,jquery禁用按钮click点击
			jquery禁用a标签方法1 $(document).ready(function () { $("a").each(function () { var textValue = $ ... 
- PHP数组操作——获取数组最后一个值的方法
			php开发过程中,可能经常需要对取出的数组要获取数组的最后健或值.在这里总结了三个方法,并且跟据他们三个方法在一些情况下如何使用的条件限制进行了说明. <?php $array=array(1, ... 
- 如何解决PHP中文乱码问题
			如何解决PHP中文乱码问题 一.解决HTML中中文乱码问题方法 1.在head标签里面加入UTF8编码(国际化编码):UTF-8是没有国家的编码,也就是独立于任何一种语言,任何语言都可以使用的. ... 
- 可视化查看MongoDB - MongoVUE
			OS:Window 7 1.下载安装MongoVUE:http://www.mongovue.com/downloads/ 2.运行MongoVUE,点击“OK”按钮,使用免费版 3.选择一个已经存在 ... 
- 实现目标文件与源码分开的makefile测试实验
			uboot提供了两种编译策略,即可以将生成的目标文件与源码混在一起,也可以将生成的目标文件与源码分开.通过对uboot Makefile的分析,笔者编写了一个简单的实现这种功能的Makfile. 顶层 ... 
- What does it mean for an algorithm to be fair
			What does it mean for an algorithm to be fair In 2014 the White House commissioned a 90-day study th ... 
- DJANGO,获取当前用户名,用户组名,用户组权限
			样例,为下一步自定义用户权限作一下代码准备: def get_context_data(self, **kwargs): if self.request.user.is_authenticated() ... 
