我正在使用 NASM 在 Ubuntu 上組裝一個 x86-64 程式:
nasm -f elf64 -g -F dwarf -o foo.o foo.asm
ld -o foo foo.o
資源:
section .text
global _start
_start:
mov rax, 60 ;SYS_exit
mov rdi, 0 ;EXIT_SUCCESS
syscall
使用 GDB 除錯程式不會顯示指令來自哪個檔案或行號。例如,break _start顯示“Breakpoint 1 at 0x401000”而不是“Breakpoint 1 at 0x400080: file foo.asm, line 4”。如本博文所示。切換到layout regs顯示“無可用源”,而不是在源中找到當前指令的位置。list確實顯示了源,但在進入下一條指令時它會切換回“無可用源”。
objdump -g foo似乎表明所需的除錯資訊在那里:
foo: file format elf64-x86-64
...
The File Name Table (offset 0x1c):
Entry Dir Time Size Name
1 0 0 0 foo.asm
Line Number Statements:
[0x00000028] Extended opcode 2: set Address to 0x401000
[0x00000033] Special opcode 8: advance Address by 0 to 0x401000 and Line by 3 to 4
[0x00000034] Special opcode 76: advance Address by 5 to 0x401005 and Line by 1 to 5
[0x00000035] Special opcode 76: advance Address by 5 to 0x40100a and Line by 1 to 6
[0x00000036] Advance PC by 2 to 0x40100c
[0x00000038] Extended opcode 1: End of Sequence
Ubuntu 22.04、NASM 2.15.05、GDB 12.09
uj5u.com熱心網友回復:
我設定了一個 Ubuntu 22.04 VM,發現我可以重現您在那里看到的問題,但是,在我的本地計算機上,我無法重現該問題。
我注意到在我的本地機器上我使用的是 nasm 2.14.02,而在 Ubuntu 機器上我使用的是 2.15.05。
如果我們檢查objdump -g兩個可執行檔案的輸出,這是我從作業可執行檔案中看到的部分內容:
Contents of the .debug_info section (loaded from foo):
Compilation Unit @ offset 0x0:
Length: 0x45 (32-bit)
Version: 3
Abbrev Offset: 0x0
Pointer Size: 8
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_low_pc : 0x401000
<14> DW_AT_high_pc : 0x40100c
<1c> DW_AT_stmt_list : 0x0
<20> DW_AT_name : foo.asm
<28> DW_AT_producer : NASM 2.14.02
<35> DW_AT_language : 32769 (MIPS assembler)
<1><37>: Abbrev Number: 2 (DW_TAG_subprogram)
<38> DW_AT_low_pc : 0x401000
<40> DW_AT_frame_base : 0x0 (location list)
<1><44>: Abbrev Number: 0
這是損壞的可執行檔案中的相同部分:
Contents of the .debug_info section (loaded from foo):
Compilation Unit @ offset 0x0:
Length: 0x45 (32-bit)
Version: 3
Abbrev Offset: 0x0
Pointer Size: 8
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<c> DW_AT_low_pc : 0x401000
<14> DW_AT_high_pc : 0x401000
<1c> DW_AT_stmt_list : 0x0
<20> DW_AT_name : foo.asm
<28> DW_AT_producer : NASM 2.15.05
<35> DW_AT_language : 32769 (MIPS assembler)
<1><37>: Abbrev Number: 2 (DW_TAG_subprogram)
<38> DW_AT_low_pc : 0x401000
<40> DW_AT_frame_base : 0x0 (location list)
<1><44>: Abbrev Number: 0
關鍵的區別是DW_AT_high_pc2.15.05 nasm 似乎是錯誤的。我手動進入并編輯了這個值,突然之間,我可以很好地除錯以前損壞的可執行檔案。
這似乎是 nasm 2.15.05 的回歸,您應該考慮降級 nasm(我認為 2.15.05 是當前的最新版本),或者提交 nasm 錯誤。
uj5u.com熱心網友回復:
IIRC,GDB 作業正常 NASM 的默認 STABS 輸出,所以讓它使用它而不是 DWARF。Jester 說 GNU 工具使用 NASM 不知道如何制作的較新的 DWARF 格式。但它們仍然支持 DWARF 取代的 STABS 格式。STABS 非常適合將源代碼行映射到地址的簡單任務,這是像 NASM 這樣的簡單源語言所需要的。
只需使用nasm -g沒有-F選項。
或者也省略掉-g,你仍然會得到符號名稱,而且除了基本標簽名稱之外,我在手寫 asm 中的除錯資訊從來沒有太多用處。(當然還有節頭,在可執行檔案中也不需要,只是程式頭。如果您嘗試在 FASM 直接創建的可執行檔案上使用 GDB,您會發現。)
我總是使用layout nafterlayout reg來切換到暫存器 反匯編。過去就是這樣layout reg;我不確定當前行為是 GDB 錯誤還是什么。(在某些以前的版本中,兩者layout next/prev都是必需的,就像它認為配置設定與 UI 實際顯示的內容不同步)。
無論如何,我基本上從不希望 GDB 顯示.asm源代碼,我希望它顯示我正在運行的任何東西的規范反匯編,以防我寫的東西與它的外觀不同。
在你的 asm 源中使用有意義的標簽名稱將導致 GDB 顯示執行sieve.crossout或其他。盡管有很多條件分支不太好,因為每個分支目標看起來都像是 GDB 的完整標簽。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/495925.html
