【軟件開發底層知識修煉】六 Binutils輔助工具之- addr2line與strip工具

學習交流加linux

  • 我的qq: 1126137994
  • 我的微信: liu1126137994
  • 學習交流資源分享qq羣: 962535112

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

在這裏插入圖片描述

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

一、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程序ui

#include <stdio.h>

int* g_pointer;

void func() {
	*g_pointer = (int)"D.T.Software";

    return;
}
複製代碼

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

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

運行程序.net

  • ./lyy

顯示結果爲: debug

在這裏插入圖片描述

其實結果也在乎料之中。咱們分析程序很容易知道,func函數中 *g_pointer = (int)"D.T.Software"; 這句話,使得在0地址賦值了。由於int* g_pointer;只是定義了g_pointer卻沒有賦值,那麼g_pointer實際上一開始是指向0地址,後面又對它進行賦值。至關於對0地址進行操做。

可是咱們知道0地址,是不能被操做的。因此會產生段錯誤。這個程序很短,問題咱們很容易發現。可是若是這個歌程序有一千行,一萬行的話,那麼問題就很難定位到。此時addr2line工具就可以上場。

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

  1. 首先開啓core dump選項。使用命令ulimit -c unlimited。開啓這個選項後,在運行可執行程序的時候,會將程序崩潰前最後一刻的內存狀態信息,轉儲(保存)到一個core文件。這個文件叫作核心轉儲文件。咱們能夠經過讀取該文件,獲取一些用於調試的信息。

    在這裏插入圖片描述

  2. 開啓core dump選項後,再次運行可執行程序,來生成core文件。

在這裏插入圖片描述

咱們能夠看到,段錯誤後面顯示核心已轉儲。此時查看當前目錄的話,就能夠看到core文件。

在這裏插入圖片描述

  1. 讀取core文件,獲取IP寄存器的值(IP寄存器存的是當前CPU所要執行指令的值,程序崩潰前最後一刻的IP寄存器的值,就是崩潰的指令地址)。使用dmesg core 命令讀取core文件的內容,顯示內容最後部分以下:

在這裏插入圖片描述

能夠看到,最後一刻IP寄存器的值爲0x080483d1.出問題的代碼就在這個地址處。可是咱們沒法知道這個地址處究竟是個啥。可是能夠利用addr2line工具,將這個地址轉換爲代碼中對應的行號。

  1. 使用addr2line定位對應的代碼行。使用命令:addr2line 0x080483d1 -f -e lyy

在這裏插入圖片描述

很明顯,已經找打緣由,是func.c程序的第7行。當從兩萬行大代碼中找到這個錯誤,也是很激動的!!!

二、strip工具

實際上,addr2line可以正常工做,必須依賴於程序的調試信息。而咱們在編譯程序的時候,也確實讓程序生成了調試信息。如上編譯的時候帶的-g選項。

當可執行程序裏面帶有大量的調試信息,會致使可執行程序,很是的大。若是在大型的軟件中,軟件在發佈以前,確定是要將這些調試信息去掉,好讓發佈出去的程序佔用內存空間更小,否則程序太大,對用戶來講也是很是不友好的。

其實這就是所謂的release版本的程序。在發佈以前,還須要調試的程序,咱們稱爲debug版本程序。

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

在這裏插入圖片描述

使用strip將調試信息剔除後大小爲5512:

在這裏插入圖片描述

結果顯而易見!!!

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

三、總結

  • addr2line用於將代碼地址轉換爲對應的行號。經常使用於定位內存訪問錯誤的問題
  • 理解core dump選項。
  • strip能夠剔除目標程序中的調試信息,從而能夠減少目標代碼的大小,提高目標程序的執行效率。
  • 學會使用上述兩個工具。
相關文章
相關標籤/搜索