日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > php >内容正文

php

php 打印函数调用栈,利用backtrace和backtrace_symbols函数打印调用栈信息

發(fā)布時(shí)間:2024/9/18 php 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php 打印函数调用栈,利用backtrace和backtrace_symbols函数打印调用栈信息 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本帖最后由 kylin_try 于 2017-2-6 08:41 編輯

在頭文件"execinfo.h"中聲明了三個(gè)函數(shù)用于獲取當(dāng)前線程的函數(shù)調(diào)用堆棧。

#include

int backtrace(void **buffer, intsize);

char **backtrace_symbols(void *const *buffer, intsize);

void backtrace_symbols_fd(void *const *buffer, intsize, intfd);

man 幫助:

DESCRIPTION? ?? ?? ?backtrace() returns a backtrace for the calling program, in the array pointed to by buffer.??A backtrace is the series of currently active function calls for the program.??Each item in the array pointed to by buffer is of type void *, and is the return address from the corresponding stack frame.??The size argument specifies the maximum number of addresses that can be stored in buffer.??If the backtrace is larger than size, then the addresses corresponding to the size most recent function calls are returned; to obtain the complete backtrace, make sure that buffer and size are large enough.Given the set of addresses returned by backtrace() in buffer, backtrace_symbols() translates the addresses into an array of strings that describe the addresses symbolically. The size argument specifies the number of addresses in buffer.??The symbolic representation of each address consists of the function name (if this can be determined), a hexadecimal offset into the function, and the actual return address (in hexadecimal). The address of the array of string pointers is returned as the function result of backtrace_symbols().??This array ismalloc(3)ed by backtrace_symbols(), and must be freed by the caller.??(The strings pointed to by the array of pointers need not and should not be freed.)backtrace_symbols_fd() takes the same buffer and size arguments as backtrace_symbols(), but instead of returning an array of strings to the caller,it writes the strings, one per line, to the file descriptor fd.??backtrace_symbols_fd() does not call malloc(3), and so can be employed in situations where the latter function might fail.

int backtrace(void **buffer,int size)

該函數(shù)用與獲取當(dāng)前線程的調(diào)用堆棧,獲取的信息將會(huì)被存放在buffer中,它是一個(gè)指針數(shù)組。參數(shù) size 用來(lái)指定buffer中可以保存多少個(gè)void* 元素。函數(shù)返回值是實(shí)際獲取的指針個(gè)數(shù),最大不超過(guò)size大小在buffer中的指針實(shí)際是從堆棧中獲取的返回地址,每一個(gè)堆棧框架有一個(gè)返回地址。

注意某些編譯器的優(yōu)化選項(xiàng)對(duì)獲取正確的調(diào)用堆棧有干擾,另外內(nèi)聯(lián)函數(shù)沒(méi)有堆棧框架;刪除框架指針也會(huì)使無(wú)法正確解析堆棧內(nèi)容

char ** backtrace_symbols (void *const *buffer, int size)

backtrace_symbols將從backtrace函數(shù)獲取的信息轉(zhuǎn)化為一個(gè)字符串?dāng)?shù)組. 參數(shù)buffer應(yīng)該是從backtrace函數(shù)獲取的數(shù)組指針,size是該數(shù)組中的元素個(gè)數(shù)(backtrace的返回值),函數(shù)返回值是一個(gè)指向字符串?dāng)?shù)組的指針,它的大小同buffer相同.每個(gè)字符串包含了一個(gè)相對(duì)于buffer中對(duì)應(yīng)元素的可打印信息.它包括函數(shù)名,函數(shù)的偏移地址,和實(shí)際的返回地址

現(xiàn)在,只有使用ELF二進(jìn)制格式的程序和苦衷才能獲取函數(shù)名稱和偏移地址.在其他系統(tǒng),只有16進(jìn)制的返回地址能被獲取.另外,你可能需要傳遞相應(yīng)的標(biāo)志給鏈接器,以能支持函數(shù)名功能(比如,在使用GNU ld的系統(tǒng)中,你需要傳遞(-rdynamic))

backtrace_symbols生成的字符串都是malloc出來(lái)的,但是不要最后一個(gè)一個(gè)的free,因?yàn)閎acktrace_symbols是根據(jù)backtrace給出的call stack層數(shù),一次性的malloc出來(lái)一塊內(nèi)存來(lái)存放結(jié)果字符串的,所以,像上面代碼一樣,只需要在最后,free backtrace_symbols的返回指針就OK了。這一點(diǎn)backtrace的manual中也是特別提到的。

注意:如果不能為字符串獲取足夠的空間函數(shù)的返回值將會(huì)為NULL

void backtrace_symbols_fd (void *const *buffer, int size, int fd)

backtrace_symbols_fd與backtrace_symbols 函數(shù)具有相同的功能,不同的是它不會(huì)給調(diào)用者返回字符串?dāng)?shù)組,而是將結(jié)果寫入文件描述符為fd的文件中,每個(gè)函數(shù)對(duì)應(yīng)一行.它不需要調(diào)用malloc函數(shù),因此適用于有可能調(diào)用該函數(shù)會(huì)失敗的情況。man手冊(cè)中示例:#include

#include

#include

#include

void

myfunc3(void)

{

int j, nptrs;

#define SIZE 100

void *buffer[100];

char **strings;

nptrs = backtrace(buffer, SIZE);

printf("backtrace() returned %d addresses\n", nptrs);

/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)

would produce similar output to the following: */

strings = backtrace_symbols(buffer, nptrs);

if (strings == NULL) {

perror("backtrace_symbols");

exit(EXIT_FAILURE);

}

for (j = 0; j < nptrs; j++)

printf("%s\n", strings[j]);

free(strings);

}

static void? ?/* "static" means don't export the symbol... */

myfunc2(void)

{

myfunc3();

}

void

myfunc(int ncalls)

{

if (ncalls > 1)

myfunc(ncalls - 1);

else

myfunc2();

}

int

main(int argc, char *argv[])

{

if (argc != 2) {

fprintf(stderr, "%s num-calls\n", argv[0]);

exit(EXIT_FAILURE);

}

myfunc(atoi(argv[1]));

exit(EXIT_SUCCESS);

}

結(jié)果:

總結(jié):使用以下幾個(gè)函數(shù)既可完成堆棧信息的打印

int backtrace (void **buffer, int size)

char ** backtrace_symbols (void *const *buffer, int size)

char* abi::__cxa_demangle

(

const char * mangled_name,

char * output_buffer,

size_t * length,

int * status

)

1. backtrace可以在程序運(yùn)行的任何地方被調(diào)用,返回各個(gè)調(diào)用函數(shù)的返回地址,可以限制最大調(diào)用棧返回層數(shù)。

2. 在backtrace拿到函數(shù)返回地址之后,backtrace_symbols可以將其轉(zhuǎn)換為編譯符號(hào),這些符號(hào)是編譯期間就確定的

3. 根據(jù)backtrace_symbols返回的編譯符號(hào),abi::__cxa_demangle可以找到具體地函數(shù)方法

轉(zhuǎn):http://www.cnblogs.com/mickole/p/3246702.html

總結(jié)

以上是生活随笔為你收集整理的php 打印函数调用栈,利用backtrace和backtrace_symbols函数打印调用栈信息的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。