目录

硬體支援

處理器一般提供以下功能供上層軟體除錯:

作業系統

Linux 提供 ptrace,Windows 提供 Win32 Debug API

除錯資訊

針對匯編語言,除錯訊息應該要能帶入以下資訊。

STABS

$ cat hello.c
main()
{
    printf("Hello world");
}
$ gcc -gstabs -S hello.c
        .file   "hello.c"
        .stabs  "hello.c",100,0,2,.Ltext0
        .text
.Ltext0:
        .stabs  "gcc2_compiled.",60,0,0,0
        .stabs  "int:t(0,1)=r(0,1);-2147483648;2147483647;",128,0,0,0
$ objdump --stabs hello
a.out:     file format elf32-i386
 
Contents of .stab section:
 
Symnum n_type n_othr n_desc n_value  n_strx String
 
-1     HdrSym 0      118    00000f24 1     
0      SO     0      2      0804841d 1      hello.c
1      OPT    0      0      00000000 9      gcc2_compiled.
2      LSYM   0      0      00000000 24     int:t(0,1)=r(0,1);-2147483648;2147483647;

DWARF

$ cat hello.c 
int main() {
  int i = 0;
 
  return 0;
}
$ gcc -g hello.c
# 觀察 DWAFT 資訊。
$ objdump --dwarf=info a.out
a.out:     file format elf32-i386
 
Contents of the .debug_info section:
 
  Compilation Unit @ offset 0x0:
   Length:        0x4f (32-bit)
   Version:       4
   Abbrev Offset: 0x0
   Pointer Size:  4
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   DW_AT_producer    : (indirect string, offset: 0x22): GNU C 4.8.2 -mtune=generic -march=i686 -g -fstack-protector      
    <10>   DW_AT_language    : 1        (ANSI C)
    <11>   DW_AT_name        : (indirect string, offset: 0x0): hello.c  
    <15>   DW_AT_comp_dir    : (indirect string, offset: 0x8): /home/chenwj/project/misc        
    <19>   DW_AT_low_pc      : 0x80483ed        
    <1d>   DW_AT_high_pc     : 0x14     
    <21>   DW_AT_stmt_list   : 0x0      
 <1><25>: Abbrev Number: 2 (DW_TAG_subprogram)
    <26>   DW_AT_external    : 1        
    <26>   DW_AT_name        : (indirect string, offset: 0x5e): main    
    <2a>   DW_AT_decl_file   : 1        
    <2b>   DW_AT_decl_line   : 1        
    <2c>   DW_AT_type        : <0x4b>   
    <30>   DW_AT_low_pc      : 0x80483ed        
    <34>   DW_AT_high_pc     : 0x14     
    <38>   DW_AT_frame_base  : 1 byte block: 9c         (DW_OP_call_frame_cfa)
    <3a>   DW_AT_GNU_all_call_sites: 1  
    <3a>   DW_AT_sibling     : <0x4b>   
 <2><3e>: Abbrev Number: 3 (DW_TAG_variable)
    <3f>   DW_AT_name        : i        
    <41>   DW_AT_decl_file   : 1        
    <42>   DW_AT_decl_line   : 2        
    <43>   DW_AT_type        : <0x4b>   
    <47>   DW_AT_location    : 2 byte block: 91 74      (DW_OP_fbreg: -12)
 <2><4a>: Abbrev Number: 0
 <1><4b>: Abbrev Number: 4 (DW_TAG_base_type)
    <4c>   DW_AT_byte_size   : 4        
    <4d>   DW_AT_encoding    : 5        (signed)
    <4e>   DW_AT_name        : int      
 <1><52>: Abbrev Number: 0

CIE & FDE

目的是要從當前棧回復調用棧的狀態。掌握此原則之後,較好理解底下的內容。

image.slidesharecdn.com_hes2011-joakley-sbratus-exploiting-the-hard-working-dwarf-110415112206-phpapp01_95_hes2011-james-oakley-and-sergey-bratusexploitingthehardworkingdwarf-24-728.jpg

底下是 DWARF Debugging Information Format 的 Appendix 5。

$ gcc -g test.c -S -o test.s
main:
.LFB0:
        .file 1 "test.c"
        .loc 1 1 0
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16   ; (a)
        .cfi_offset 6, -16       ; (b)
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6  ; (c)
        .loc 1 1 0
        movl    $0, %eax
        popq    %rbp
        .cfi_def_cfa 7, 8        ; (d)
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
$ gcc -g test.c
$ objdump -d --start-address=0x5fa --stop-address=0x605 a.out
 
00000000000005fa <main>:
 5fa:	55                   	push   %rbp
 5fb:	48 89 e5             	mov    %rsp,%rbp
 5fe:	b8 00 00 00 00       	mov    $0x0,%eax
 603:	5d                   	pop    %rbp
 604:	c3                   	retq   
 
$ objdump --dwarf=frames a.out
 
00000030 0000000000000014 00000000 CIE
  Version:               1
  Augmentation:          "zR"
  Code alignment factor: 1
  Data alignment factor: -8
  Return address column: 16
  Augmentation data:     1b
 
  DW_CFA_def_cfa: r7 (rsp) ofs 8
  DW_CFA_offset: r16 (rip) at cfa-8
  DW_CFA_nop
  DW_CFA_nop
 
00000088 000000000000001c 0000005c FDE cie=00000030 pc=00000000000005fa..0000000000000605     
  DW_CFA_advance_loc: 1 to 00000000000005fb
  DW_CFA_def_cfa_offset: 16                  (a)
  DW_CFA_offset: r6 (rbp) at cfa-16          (b)
  DW_CFA_advance_loc: 3 to 00000000000005fe
  DW_CFA_def_cfa_register: r6 (rbp)          (c)
  DW_CFA_advance_loc: 6 to 0000000000000604
  DW_CFA_def_cfa: r7 (rsp) ofs 8             (d)
  DW_CFA_nop
  DW_CFA_nop
  DW_CFA_nop

除錯器

以下描述除錯器內部資料結構。

術語

外部連結