GDB

Load Symbol File


參考資訊:
1. gdb-library-symbol-file

一般release給客戶的檔案都是移掉debug資訊的檔案,不過,在編譯release檔案時,通常會額外編譯一份具有debug symbol的檔案,如何透過這份debug檔案除錯,就是這次要介紹的東西

main.c

#include <stdio.h>

void test(int, char*);

int main(int argc, char** argv)
{
  test(1, "I am error !");
  return 0;
}

m.c

#include <stdio.h>
#include <stdlib.h>

void test(int a1, char* a2)
{
  printf("a1:%d, a2:%s\n", a1, a2);
}

編譯

$ gcc m.c -no-pie -fPIC -shared -o m.so
$ gcc m.c -no-pie -fPIC -shared -ggdb -o m.so.debug
$ gcc main.c -o main m.so

$ strip m.so
$ strip main

$ file main m.so m.so.debug
main:       ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, stripped
m.so:       ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, stripped
m.so.debug: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, with debug_info, not stripped

設定斷點在test()

$ gdb main
  GNU gdb (Debian 8.2.1-2+b3) 8.2.1
  Copyright (C) 2018 Free Software Foundation, Inc.
  License GPLv3+: GNU GPL version 3 or later 
  This is free software: you are free to change and redistribute it.
  There is NO WARRANTY, to the extent permitted by law.
  Type "show copying" and "show warranty" for details.
  This GDB was configured as "x86_64-linux-gnu".
  Type "show configuration" for configuration details.
  For bug reporting instructions, please see:
  .
  Find the GDB manual and other documentation resources online at:
      .

  For help, type "help".
  Type "apropos word" to search for commands related to "word"...
  Reading symbols from main...(no debugging symbols found)...done.

(gdb) b test
  Breakpoint 1 at 0x1030

(gdb) r
  Starting program: /home/steward/Downloads/test/main
  Breakpoint 1, 0x00007ffff7fca109 in test () from ./m.so

由於沒有debug symbol,無法看到多餘資訊

(gdb) bt
  #0  0x00007ffff7fca109 in test () from ./m.so
  #1  0x0000555555555155 in ?? ()
  #2  0x00007ffff7de509b in __libc_start_main (main=0x555555555135, argc=1, argv=0x7fffffffe178, init=, fini=, rtld_fini=,
      stack_end=0x7fffffffe168) at ../csu/libc-start.c:308
  #3  0x000055555555507a in ?? ()

(gdb) list
  1	../sysdeps/x86/dl-procinfo.c: No such file or directory.

載入具有debug symbol的檔案

(gdb) add-symbol-file m.so.debug
  add symbol table from file "m.so.debug"
  (y or n) y
  Reading symbols from m.so.debug...done.

不過,竟然還是無法看到相關資訊

(gdb) bt
  #0  0x00007ffff7fca109 in test () from ./m.so
  #1  0x0000555555555155 in ?? ()
  #2  0x00007ffff7de509b in __libc_start_main (main=0x555555555135, argc=1, argv=0x7fffffffe178, init=, fini=, rtld_fini=,
      stack_end=0x7fffffffe168) at ../csu/libc-start.c:308
  #3  0x000055555555507a in ?? ()

(gdb) list
  1	in ../sysdeps/x86/dl-procinfo.c

仔細一看,竟然有兩個斷點,代表載入兩份程式

(gdb) info b
  Num     Type           Disp Enb Address            What
  1       breakpoint     keep y   
    breakpoint already hit 1 time
  1.1                         y     0x0000000000001105 in test at m.c:5
  1.2                         y     0x00007ffff7fca109 

接著移除debug symbol檔案

(gdb) symbol-file
  Discard symbol table from `/home/steward/Downloads/test/main'? (y or n) y
  No symbol file now.

列出m.so的位址

(gdb) info sharedlibrary
  From                To                  Syms Read   Shared Object Library
  0x00007ffff7fca050  0x00007ffff7fca131  No          ./m.so
  0x00007ffff7de3320  0x00007ffff7f2939b  No          /lib/x86_64-linux-gnu/libc.so.6
  0x00007ffff7fd6090  0x00007ffff7ff3b20  No          /lib64/ld-linux-x86-64.so.2

重新加載debug symbol的檔案到m.so的原本位址

(gdb) add-symbol-file m.so.debug 0x00007ffff7fca050
  add symbol table from file "m.so.debug" at
    .text_addr = 0x7ffff7fca050
  (y or n) y
  Reading symbols from m.so.debug...done.

重新設定斷點test()

(gdb) info b
  Num     Type           Disp Enb Address            What
  1       breakpoint     keep y   0x00007ffff7fca114 in test at m.c:6
    breakpoint already hit 1 time

(gdb) del 1

(gdb) b test
  Breakpoint 2 at 0x7ffff7fca114: file m.c, line 6.

(gdb) info b
  Num     Type           Disp Enb Address            What
  2       breakpoint     keep y   0x00007ffff7fca114 in test at m.c:6

重新執行main就可以看到除錯資訊

(gdb) r
  The program being debugged has been started already.
  Start it from the beginning? (y or n) y
  Starting program: /home/steward/Downloads/test/main

  Breakpoint 2, test (a1=1, a2=0x555555556004 "I am error !") at m.c:6
  6	  printf("a1:%d, a2:%s\n", a1, a2);

(gdb) list
  1	#include 
  2	#include 
  3
  4	void test(int a1, char* a2)
  5	{
  6	  printf("a1:%d, a2:%s\n", a1, a2);
  7	}

(gdb) p a1
  $1 = 1

(gdb) p a2
  $2 = 0x555555556004 "I am error !"

(gdb) info f
  Stack level 0, frame at 0x7fffffffe080:
   rip = 0x7ffff7fca114 in test (m.c:6); saved rip = 0x555555555155
   called by frame at 0x7fffffffe088
   source language c.
   Arglist at 0x7fffffffe070, args: a1=1, a2=0x555555556004 "I am error !"
   Locals at 0x7fffffffe070, Previous frame's sp is 0x7fffffffe080
   Saved registers:
    rbp at 0x7fffffffe070, rip at 0x7fffffffe078


返回上一頁