Creating debug symbols for gdb manually
Asked Answered
C

1

6

Intro. For my compilers course I have to translate some language to assembler. Now my code has a segfault, and I have hard time debugging it. Having an ability to watch variables would simplify the process a lot, but the final asm code has only registers and their derivatives.

Question. How can I create debug symbols for gdb manually? I believe I can propagate all necessary information. Will the separate file be created or will it be part of asm? In the former case how to make gdb aware of that file?

A link to some manual is enough. I've searched for one and was only able to find "gcc -g" and some questions about generating symbol files separately.

Condolent answered 10/11, 2018 at 19:29 Comment(5)
It's normally part of the asm, with special directives to emit a section of debug info. Look at the output of gcc -S on a .c file, with and without -g. e.g. have a look at the stuff after the .section .debug_info,"",@progbits directive in godbolt.org/z/EdeTvA. (gcc compiling for Linux/ELF MIPS). What target are you compiling for, BTW? Different debug formats exist, with DWARF being the current widely-used on on Linux/ELF targets.Torritorricelli
@PeterCordes, thank you. I understand now that it's part of asm. I guess I have to read about .loc and stuff: https://mcmap.net/q/493142/-what-are-lfb-lbb-lbe-lvl-loc-in-the-compiler-generated-assembly-code. My gcc compiler is x86-64 gcc 7.3.Condolent
Yup. Or maybe just have your compiler emit comments on the asm source lines, like gcc's -fverbose-asm does (try adding it on the Godbolt link above), and assemble it with an assembler that generates debug info for asm source-level debugging. (like as -g). So you give yourself some way to single-step the asm and see some strings from your compiler attached to each instruction, naming the operands. Doesn't help so much for setting watchpoints, but can help follow the how the compiler is implementing the source logic.Torritorricelli
@PeterCordes, Can you please clarify a bit more? I can see lines like this: mov rdx, QWORD PTR [rbp-8] # tmp89, a. Do I understand correctly that compiler now knows that rdx is tmp89 and QWORD PTR [rbp-8] is a just from that? Will gcc -g <my-asm> compilation do it? If yes, this may be exactly what I need.Condolent
Yes, the comments just repeat the operand list using C variable names, or variations on tmpXX for internal temporaries. And yeah, I think gcc -g foo.s will give you the debug info to help GDB show the right asm source lines.Torritorricelli
C
0

GCC tells the last label under which the error occurs. But it doesnt give line number nor stack trace.

Introducing Jav debug I have a similar utility in cpp called rep() which via variadic template takes a maximum of 10 arguments. NASM macros doesn't support variadic macros; but it supports overloaded macros based on number of paramters.

asm_io.inc Paul A. Carter PC Assembly Language December 12, 2002

I added the debug macro

    extern read_int,  print_int, print_string, print_line
    extern read_char, print_char, print_nl
    extern sub_dump_regs, sub_dump_mem, sub_dump_math, sub_dump_stack

    extern _printf

%macro  dump_regs 1
    push dword %1
    call sub_dump_regs
%endmacro

;
; usage: dump_mem label, start-address, # paragraphs
%macro dump_mem 3
    push dword %1
    push dword %2
    push dword %3
    call sub_dump_mem
%endmacro

%macro  dump_math 1
    push dword %1
    call sub_dump_math
%endmacro

%macro dump_stack 3
    push dword %3
    push dword %2
    push dword %1
    call sub_dump_stack
%endmacro

; private macro
; number of stack used by implementation
%define __jav_len__ 5

; private macro
; saves all registers so that you get that back how you left them
%macro __jav_save_registers__ 0
    mov [esp-4*1], edx
    mov [esp-4*2], ecx
    mov [esp-4*3], eax
    mov [esp-4*4], ebx
    lahf               ; modifies eax
    mov [esp-4*5], eax
    mov eax, [esp-4*3] ; restore the value of eax
%endmacro

; private macro
; restores the registers to the values you left them in
%macro __jav_restore_registers__ 0
    pop eax
    sahf
    pop ebx
    pop eax
    pop ecx
    pop edx
%endmacro

; private macro
; gets a scalar value
%macro __jav_get__ 1
    mov ebx, dword %1
%endmacro

; private macro
; dereference and gets the scalar
%macro __jav_get__ 2
    mov ebx, %1
    mov ebx, [ebx+%2]
%endmacro

; private macro
; used to copy dword
; return value stored in ebx
%macro __jav_copy32__ 2+
    __jav_get__ %2
    mov %1, ebx
    mov ebx, [esp-4*4] ; restore the value of ebx
%endmacro

; public macro
; pass this as argument to debug macro
; dereferences obj and return scalar at index offset
%define jav_member(obj,index) { obj, index }

; param 1: string format to print
%macro debug 1
section .data
    %%msg db %1, 10, 0
section .text
    __jav_save_registers__
    __jav_copy32__ [esp-4*(__jav_len__+1)], %%msg
    sub esp, 4*(__jav_len__+1)
    call _printf
    add esp, 4*1
    __jav_restore_registers__
%endmacro

; param 1: string format to print
; param 2: arguments to string format
%macro debug 2
section .data
    %%msg db %1, 10, 0
section .text
    __jav_save_registers__
    __jav_copy32__ [esp-4*(__jav_len__+1)], %2
    __jav_copy32__ [esp-4*(__jav_len__+2)], %%msg
    sub esp, 4*(__jav_len__+2)
    call _printf
    add esp, 4*2
    __jav_restore_registers__
%endmacro

%macro debug 3
section .data
    %%msg db %1, 10, 0
section .text
    __jav_save_registers__
    __jav_copy32__ [esp-4*(__jav_len__+1)], %3
    __jav_copy32__ [esp-4*(__jav_len__+2)], %2
    __jav_copy32__ [esp-4*(__jav_len__+3)], %%msg
    sub esp, 4*(__jav_len__+3)
    call _printf
    add esp, 4*3
    __jav_restore_registers__
%endmacro

%macro debug 4
section .data
    %%msg db %1, 10, 0
section .text
    __jav_save_registers__
    __jav_copy32__ [esp-4*(__jav_len__+1)], %4
    __jav_copy32__ [esp-4*(__jav_len__+2)], %3
    __jav_copy32__ [esp-4*(__jav_len__+3)], %2
    __jav_copy32__ [esp-4*(__jav_len__+4)], %%msg
    sub esp, 4*(__jav_len__+4)
    call _printf
    add esp, 4*4
    __jav_restore_registers__
%endmacro

%macro debug 5
section .data
    %%msg db %1, 10, 0
section .text
    __jav_save_registers__
    __jav_copy32__ [esp-4*(__jav_len__+1)], %5
    __jav_copy32__ [esp-4*(__jav_len__+2)], %4
    __jav_copy32__ [esp-4*(__jav_len__+3)], %3
    __jav_copy32__ [esp-4*(__jav_len__+4)], %2
    __jav_copy32__ [esp-4*(__jav_len__+5)], %%msg
    sub esp, 4*(__jav_len__+5)
    call _printf
    add esp, 4*5
    __jav_restore_registers__
%endmacro

%macro debug 6
section .data
    %%msg db %1, 10, 0
section .text
    __jav_save_registers__
    __jav_copy32__ [esp-4*(__jav_len__+1)], %6
    __jav_copy32__ [esp-4*(__jav_len__+2)], %5
    __jav_copy32__ [esp-4*(__jav_len__+3)], %4
    __jav_copy32__ [esp-4*(__jav_len__+4)], %3
    __jav_copy32__ [esp-4*(__jav_len__+5)], %2
    __jav_copy32__ [esp-4*(__jav_len__+6)], %%msg
    sub esp, 4*(__jav_len__+6)
    call _printf
    add esp, 4*6
    __jav_restore_registers__
%endmacro

%macro debug 7
section .data
    %%msg db %1, 10, 0
section .text
    __jav_save_registers__
    __jav_copy32__ [esp-4*(__jav_len__+1)], %7
    __jav_copy32__ [esp-4*(__jav_len__+2)], %6
    __jav_copy32__ [esp-4*(__jav_len__+3)], %5
    __jav_copy32__ [esp-4*(__jav_len__+4)], %4
    __jav_copy32__ [esp-4*(__jav_len__+5)], %3
    __jav_copy32__ [esp-4*(__jav_len__+6)], %2
    __jav_copy32__ [esp-4*(__jav_len__+7)], %%msg
    sub esp, 4*(__jav_len__+7)
    call _printf
    add esp, 4*7
    __jav_restore_registers__
%endmacro

%macro debug 8
section .data
    %%msg db %1, 10, 0
section .text
    __jav_save_registers__
    __jav_copy32__ [esp-4*(__jav_len__+1)], %8
    __jav_copy32__ [esp-4*(__jav_len__+2)], %7
    __jav_copy32__ [esp-4*(__jav_len__+3)], %6
    __jav_copy32__ [esp-4*(__jav_len__+4)], %5
    __jav_copy32__ [esp-4*(__jav_len__+5)], %4
    __jav_copy32__ [esp-4*(__jav_len__+6)], %3
    __jav_copy32__ [esp-4*(__jav_len__+7)], %2
    __jav_copy32__ [esp-4*(__jav_len__+8)], %%msg
    sub esp, 4*(__jav_len__+8)
    call _printf
    add esp, 4*8
    __jav_restore_registers__
%endmacro

%macro debug 9
section .data
    %%msg db %1, 10, 0
section .text
    __jav_save_registers__
    __jav_copy32__ [esp-4*(__jav_len__+1)], %9
    __jav_copy32__ [esp-4*(__jav_len__+2)], %8
    __jav_copy32__ [esp-4*(__jav_len__+3)], %7
    __jav_copy32__ [esp-4*(__jav_len__+4)], %6
    __jav_copy32__ [esp-4*(__jav_len__+5)], %5
    __jav_copy32__ [esp-4*(__jav_len__+6)], %4
    __jav_copy32__ [esp-4*(__jav_len__+7)], %3
    __jav_copy32__ [esp-4*(__jav_len__+8)], %2
    __jav_copy32__ [esp-4*(__jav_len__+9)], %%msg
    sub esp, 4*(__jav_len__+9)
    call _printf
    add esp, 4*9
    __jav_restore_registers__
%endmacro

%macro debug 10
section .data
    %%msg db %1, 10, 0
section .text
    __jav_save_registers__
    __jav_copy32__ [esp-4*(__jav_len__+1)], %10
    __jav_copy32__ [esp-4*(__jav_len__+2)], %9
    __jav_copy32__ [esp-4*(__jav_len__+3)], %8
    __jav_copy32__ [esp-4*(__jav_len__+4)], %7
    __jav_copy32__ [esp-4*(__jav_len__+5)], %6
    __jav_copy32__ [esp-4*(__jav_len__+6)], %5
    __jav_copy32__ [esp-4*(__jav_len__+7)], %4
    __jav_copy32__ [esp-4*(__jav_len__+8)], %3
    __jav_copy32__ [esp-4*(__jav_len__+9)], %2
    __jav_copy32__ [esp-4*(__jav_len__+10)], %%msg
    sub esp, 4*(__jav_len__+10)
    call _printf
    add esp, 4*10
    __jav_restore_registers__
%endmacro
Coatbridge answered 11/1 at 14:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.