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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【软件开发底层知识修炼】六 Binutils辅助工具之- addr2line与strip工具

發布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【软件开发底层知识修炼】六 Binutils辅助工具之- addr2line与strip工具 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

學習交流加

  • 個人qq:
    1126137994
  • 個人微信:
    liu1126137994
  • 學習交流資源分享qq群:
    962535112

上一篇文章我們學習了gcc編譯器的相關內容。點擊查看上一篇文章:gcc編譯器。本篇文章接著上一篇文章,學習GNU為GCC提供的輔助開發工具集Binutils。Binutils工具集,主要是用于在代碼調試的時候,定位bug的一些手段。我們主要學習以下幾個工具的使用:

本篇文章先學習使用addr2line與strip工具。

文章目錄

  • 1、addr2line工具
  • 2、strip工具
  • 3、總結

1、addr2line工具

首先我們要知道,gcc編譯程序的時候,加上-g選項,表示在目標文件中生成調試信息。幾乎所有調試輔助工具,都依賴于程序的調試信息。

addr2line工具。顧名思義,可以將地址轉換為行號。它常用于分析定位內存訪問錯誤的問題。以實際例子為例:

test.c程序

#include <stdio.h>int g_global = 0; int g_test = 1;extern int* g_pointer; extern void func();int main(int argc, char *argv[]) {printf("&g_global = %p\n", &g_global);printf("&g_test = %p\n", &g_test);printf("&g_pointer = %p\n", &g_pointer);printf("g_pointer = %p\n", g_pointer);printf("&func = %p\n", &func);printf("&main = %p\n", &main);func();return 0; }

func.c程序

#include <stdio.h>int* g_pointer;void func() {*g_pointer = (int)"D.T.Software";return; }

我們在linux下編譯以下程序(注意我使用gcc-4.4.5版本編譯沒有警告顯示。但是使用較高版本的gcc編譯器,可能會有警告。這里我們忽略警告):

  • gcc -g func.c test.c -o lyy

運行程序

  • ./lyy

顯示結果為:

其實結果也在意料之中。我們分析程序很容易知道,func函數中 *g_pointer = (int)"D.T.Software"; 這句話,使得在0地址賦值了。因為int* g_pointer;只是定義了g_pointer卻沒有賦值,那么g_pointer實際上一開始是指向0地址,后面又對它進行賦值。相當于對0地址進行操作。

但是我們知道0地址,是不能被操作的。所以會產生段錯誤。這個程序很短,問題我們很容易發現。但是如果這個歌程序有一千行,一萬行的話,那么問題就很難定位到。此時addr2line工具就能夠上場。

下面來說明如何使用addr2line工具。

  • 首先開啟core dump選項。使用命令ulimit -c unlimited。開啟這個選項后,在運行可執行程序的時候,會將程序崩潰前最后一刻的內存狀態信息,轉儲(保存)到一個core文件。這個文件叫做核心轉儲文件。我們可以通過讀取該文件,獲取一些用于調試的信息。

  • 開啟core dump選項后,再次運行可執行程序,來生成core文件。

  • 我們可以看到,段錯誤后面顯示核心已轉儲。此時查看當前目錄的話,就可以看到core文件。

  • 讀取core文件,獲取IP寄存器的值(IP寄存器存的是當前CPU所要執行指令的值,程序崩潰前最后一刻的IP寄存器的值,就是崩潰的指令地址)。使用dmesg core 命令讀取core文件的內容,顯示內容最后部分如下:
  • 可以看到,最后一刻IP寄存器的值為0x080483d1.出問題的代碼就在這個地址處。但是我們無法知道這個地址處到底是個啥。但是可以利用addr2line工具,將這個地址轉換為代碼中對應的行號。

  • 使用addr2line定位對應的代碼行。使用命令:addr2line 0x080483d1 -f -e lyy
  • 很明顯,已經找打原因,是func.c程序的第7行。當從兩萬行大代碼中找到這個錯誤,也是很激動的!!!

    2、strip工具

    實際上,addr2line能夠正常工作,必須依賴于程序的調試信息。而我們在編譯程序的時候,也確實讓程序生成了調試信息。如上編譯的時候帶的-g選項。

    當可執行程序里面帶有大量的調試信息,會導致可執行程序,非常的大。如果在大型的軟件中,軟件在發布之前,肯定是要將這些調試信息去掉,好讓發布出去的程序占用內存空間更小,不然程序太大,對用戶來說也是非常不友好的。

    其實這就是所謂的release版本的程序。在發布之前,還需要調試的程序,我們稱為debug版本程序。

    那么如何剔除調試信息?使用strip工具!如下圖是release版本的程序大小為9074:

    使用strip將調試信息剔除后大小為5512:

    結果顯而易見!!!

    還有其他工具,放在下一篇文章學習!!!

    3、總結

    • addr2line用于將代碼地址轉換為對應的行號。常用于定位內存訪問錯誤的問題
    • 理解core dump選項。
    • strip可以剔除目標程序中的調試信息,從而可以減小目標代碼的大小,提升目標程序的執行效率。
    • 學會使用上述兩個工具。

    本文章參考狄泰軟件學院相關課程
    想學習的可以加狄泰軟件學院群,
    群聊號碼:199546072

    學習探討加個人(可以免費幫忙下載CSDN資源):
    qq:1126137994
    微信:liu1126137994

    總結

    以上是生活随笔為你收集整理的【软件开发底层知识修炼】六 Binutils辅助工具之- addr2line与strip工具的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。