extremeaxe5
extremeaxe5

Reputation: 815

Understanding output of gdb `where` command

I am debugging the following program (which is correct).

[OP@localhost 04]$ cat factorial.s
    .section .text
    .globl _start
    .globl _factorial
_start:
    push $4
    call factorial
    add $8, %rsp

    mov %rax, %rdi
    mov $60, %rax
    syscall

    .type factorial, @function
factorial:
    # Parameters
    #   n : int
    #       Number to take factorial of
    push %rbp
    mov %rsp, %rbp

    mov 0x10(%rbp), %rax
if: 
    cmp $1, %rax
    jne else

    jmp end_if
else:
    dec %rax
    push %rax
    call factorial
    add $8, %rsp

    imul 0x10(%rbp), %rax
end_if: 
    pop %rbp
    ret

I've set a breakpoint at the factorial function, and continued twice. Examining the value of %rsp, I find that it is

(gdb) print/$rsp
$1 = 0x7fffffffd698

Examining the region surrounding that, I find

(gdb) x /10xg 0x7fffffffd690
0x7fffffffd690: 0x0000000000000000  0x00007fffffffd6b0
0x7fffffffd6a0: 0x0000000000401030  0x0000000000000002
0x7fffffffd6b0: 0x00007fffffffd6c8  0x0000000000401030
0x7fffffffd6c0: 0x0000000000000003  0x0000000000000000
0x7fffffffd6d0: 0x0000000000401007  0x0000000000000004

Roughly, this is as one would expect. However, the output of where is the following:

(gdb) where
#0  0x000000000040101b in factorial ()
#1  0x0000000000401030 in else ()
#2  0x0000000000000002 in ?? ()
#3  0x00007fffffffd6c8 in ?? ()
#4  0x0000000000401030 in else ()
#5  0x0000000000000003 in ?? ()
#6  0x0000000000000000 in ?? ()

Which I cannot seem to understand. It seems to be reading the stack in order, but I don't know where the number 0x40101b came from (that number is nowhere on the stack), and I'm not sure why it stopped there, as it does not print out the stack frame for the initial function call to factorial.

Upvotes: 1

Views: 961

Answers (1)

Employed Russian
Employed Russian

Reputation: 213799

However, the output of where is the following:

On x86_64, GDB expects a program to have proper DWARF unwind info (which your program completely lacks). (Documentation on how to insert such info using .cfi directives.)

Without DWARF info, GDB makes guesses using certain heuristics. Here GDB treats else as if it were a function, and tries to find its caller, with disastrous results. Effectively, where will not work well for a program without DWARF unwind info, unless that program only uses C function labels and uses frame pointers.

Upvotes: 1

Related Questions