欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
巧用backtrace系列函數,在不具備gdb環(huán)境的Linux系統上大致定位...

1: 段錯誤產(chǎn)生的原因

簡(jiǎn)而言之,產(chǎn)生段錯誤就是訪(fǎng)問(wèn)了錯誤的內存段,一般是你沒(méi)有權限,或者根本就不存在對應的物理內存,
尤其常見(jiàn)的是訪(fǎng)問(wèn)0地址.一旦一個(gè)程序發(fā)生了越界訪(fǎng)問(wèn),系統就采取內存保護措施,并給那個(gè)程序發(fā)送
SIGSEGV信號,程序接到那個(gè)信號后就知道segmentation fault出現了。

想對”段錯誤”有更詳細的了解可以去閱讀“Linux下的段錯誤產(chǎn)生的原因及調試方法” 這篇文章,本文的
內容基本是從那文章里提取出來(lái)的。

2: SIGSEGV信號處理函數

程序接到SIGSEGV信號后的缺省處理是退出程序,這也是為什么總是看到程序打印一個(gè)“segmentation fault”
信息后就消失了。我們可以使用 signal(SIGSEGV, &your_function);函數來(lái)接管SIGSEGV信號的處理,讓
程序在發(fā)生段錯誤后,自動(dòng)調用我們準備好的函數,從而在那個(gè)函數里來(lái)獲取當前函數調用棧。

3: libc的Backtraces函數

在GDB里,可以簡(jiǎn)單的使用bt命令就可以獲取函數調用棧,但如何通過(guò)代碼獲取當前函數調用棧?
這里我們可以通過(guò)libc庫提供的Backtraces系列函數。

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 file execinfo.h declares three functions that obtain and            manipulate backtraces of the current thread.

4: 實(shí)現步驟

4.1 在你的工程中添加如下代碼:

#include <execinfo.h>            #include <stdio.h>            #include <stdlib.h>            #include <signal.h>                         void dump(int signo)            {            void *array[30];            size_t size;            char **strings;            size_t i;                         size = backtrace (array, 30);            strings = backtrace_symbols (array, size);                         fprintf (stderr,"Obtained %zd stack frames.nm", size);                         for (i = 0; i < size; i++)            fprintf (stderr,"%sn", strings[i]);                         free (strings);                         exit(0);            }                         Debug_Printf_FrameInfos()            {            signal(SIGSEGV, &dump);            }

4.2 在mian函數開(kāi)始位置處調用 Debug_Printf_FrameInfos() 函數
4.3 在編譯程序時(shí) 加上 -g 選項

5 定位出錯函數地址實(shí)例

這里以 test.c 為例,來(lái)查找出錯函數地址

#include <execinfo.h>             #include <stdio.h>            #include <stdlib.h>            #include <signal.h>                         void dump(int signo)            {            void *array[30];            size_t size;            char **strings;            size_t i;                         size = backtrace (array, 30);            strings = backtrace_symbols (array, size);                         fprintf (stderr,"Obtained %zd stack frames.nm", size);                         for (i = 0; i <= size; i++)            fprintf (stderr,"%s\n", strings[i]);                         free (strings);            exit(0);            }                         Debug_Printf_FrameInfos()            {            signal(SIGSEGV, dump);            }                         void func_c()            {            * ((volatile char *) 0x0) = 0x999;            }            void func_b()            {            func_c();            }            void func_a()            {            func_b();            }            int main()            {            Debug_Printf_FrameInfos();            func_a();            return 0;            }

該例程調用序列為:
main() -> func_a() -> func_b() -> func_c() -> 出錯

5.1編譯程序:

# gcc -g test.c -o test

注:選項 -rdynamic 可用來(lái)通知鏈接器將所有符號添加到動(dòng)態(tài)符號表中,如果你的鏈接器支持-rdynamic的話(huà),
建議將其加上,即
# gcc -rdynamic -g test.c -o test

5.2 運行 test程序:

 #  ./test            Obtained 7 stack frames.nm./a.out [0x80484e3]            [0xb7f70420]            ./a.out [0x804859d]            ./a.out [0x80485a7]            ./a.out [0x80485c4]            /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0) [0xb7e1e450]            ./a.out [0x8048461]            Segmentation fault

如果編譯似加了-rdynamic選項 的話(huà),將打印如下信息

# ./test             Obtained 7 stack frames.nm./test(dump+0x1f) [0x80487c3]            [0xb7fbb420]            ./test(func_b+0x8) [0x804887d]            ./test(func_a+0x8) [0x8048887]            ./test(main+0x1b) [0x80488a4]            /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0) [0xb7e69450]            ./test [0x8048741]

打印信息比沒(méi)加-rdynamic的程序多出了一個(gè)函數名稱(chēng)+偏移地址..(func_b+0×8)

5.3 使用objdump獲取程序所有符合

objdump -d ./test > tmp.txt

5.4 分析和查找

在tmp.txt 中查找0×80485ad的地址,你會(huì )發(fā)現如下信息:
08048595 :
8048595: 55 push %ebp
8048596: 89 e5 mov %esp,%ebp
8048598: e8 eb ff ff ff call 8048588
804859d: 5d pop %ebp
804859e: c3

其中 804859d 是調用( call 8048588 )c函數后的地址,雖然并沒(méi)有直接定位到C函數,
通過(guò)匯編代碼,基本可以推出是在C函數出現問(wèn)題了。(pop指令不會(huì )導致段錯誤的)

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
c中如何打印函數調用堆棧?
Linux調用棧獲取分析及實(shí)現
嵌入式C代碼調試利器---backtrace
嵌入式段錯誤的3種調試方法匯總!
Linux 常用命令:開(kāi)發(fā)調試篇
第一時(shí)間捕獲段錯誤(segment fault)的詳細信息
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久