I've set the disassembly-flavor of the gdb-debugger to Intel (both: su & normal user), but anyway it's still showing the assembly-code in AT&T notation:
patrick#localhost:~/Dokumente/Projekte$ gdb -q ./a.out
Reading symbols from ./a.out...done.
(gdb) break main
Breakpoint 1 at 0x40050e: file firstprog.c, line 5.
(gdb) run
Starting program: /home/patrick/Dokumente/Projekte/a.out
Breakpoint 1, main () at firstprog.c:5
5 for(i=0; i < 10; i++)
(gdb) show disassembly
The disassembly flavor is "intel".
(gdb) info registers
rax 0x400506 4195590
rbx 0x0 0
rcx 0x0 0
rdx 0x7fffffffe2d8 140737488347864
rsi 0x7fffffffe2c8 140737488347848
rdi 0x1 1
rbp 0x7fffffffe1e0 0x7fffffffe1e0
(gdb) info register eip
Invalid register `eip'
I did restart the computer. My OS is Kali Linux amd64.
I have the following questions:
Why is gdb still showing the AT&T notation?
Why is the register EIP (instruction pointer) shown as invalid register?
You are misunderstanding what disassembly flavour means. It means exactly that: what the disassembly looks like when you view machine code in a human-readable(ish) form.
To print registers (or use registers in any other context), you need to use $reg, such as $rip or $pc, $eax, etc.
If I disassemble one of my programs with at&t syntax, gdb shows this:
0x00000000007378f0 <+0>: push %rbp
0x00000000007378f1 <+1>: mov %rsp,%rbp
0x00000000007378f4 <+4>: sub $0x20,%rsp
0x00000000007378f8 <+8>: movl $0x0,-0x4(%rbp)
0x00000000007378ff <+15>: mov %edi,-0x8(%rbp)
0x0000000000737902 <+18>: mov %rsi,-0x10(%rbp)
=> 0x0000000000737906 <+22>: mov -0x10(%rbp),%rsi
0x000000000073790a <+26>: mov (%rsi),%rdi
0x000000000073790d <+29>: callq 0x737950 <FindLibPath(char const*)>
0x0000000000737912 <+34>: xor %eax,%eax
Then do this:
(gdb) set disassembly-flavor intel
(gdb) disass main
Dump of assembler code for function main(int, char**):
0x00000000007378f0 <+0>: push rbp
0x00000000007378f1 <+1>: mov rbp,rsp
0x00000000007378f4 <+4>: sub rsp,0x20
0x00000000007378f8 <+8>: mov DWORD PTR [rbp-0x4],0x0
0x00000000007378ff <+15>: mov DWORD PTR [rbp-0x8],edi
0x0000000000737902 <+18>: mov QWORD PTR [rbp-0x10],rsi
=> 0x0000000000737906 <+22>: mov rsi,QWORD PTR [rbp-0x10]
0x000000000073790a <+26>: mov rdi,QWORD PTR [rsi]
0x000000000073790d <+29>: call 0x737950 <FindLibPath(char const*)>
0x0000000000737912 <+34>: xor eax,eax
and you can see the difference. But the names of registers and how you use registers on the gdb command-line isn't changing, you need a $reg in both cases.
Related
This question already has an answer here:
GDB - Address of breakpoint
(1 answer)
Closed 1 year ago.
Here is my function with line numbers
8 | void function(char* string) {
9 | char buffer[16];
10| strcpy(buffer,string);
11| }
Here is gdb disassemble function output
0x000011d4 <+0>: push %ebp
0x000011d5 <+1>: mov %esp,%ebp
0x000011d7 <+3>: push %ebx
0x000011d8 <+4>: sub $0x14,%esp
0x000011db <+7>: call 0x123d <__x86.get_pc_thunk.ax>
0x000011e0 <+12>: add $0x2e20,%eax
0x000011e5 <+17>: sub $0x8,%esp <---- I want Break point here
0x000011e8 <+20>: pushl 0x8(%ebp)
0x000011eb <+23>: lea -0x18(%ebp),%edx
0x000011ee <+26>: push %edx
0x000011ef <+27>: mov %eax,%ebx
0x000011f1 <+29>: call 0x1030 <strcpy#plt>
0x000011f6 <+34>: add $0x10,%esp
0x000011f9 <+37>: nop
0x000011fa <+38>: mov -0x4(%ebp),%ebx
0x000011fd <+41>: leave
0x000011fe <+42>: ret
If I set break point at 0x000011e5 using the following command,
(gdb) b *0x000011e5
and run the program, gdb ignores all breakpoints and exits.
But, if I specify,
b 9, it works.
Here is the output
(gdb) b 10
Breakpoint 1 at 0x4011e5: file hello.c, line 10.
Why are the address different ?
Why are the address different
Because you have a position-independent executable, which is linked at address 0, but relocated to a different address at runtime.
I believe this worked perfectly previously, but maybe I just forgot the correct syntax.
(gdb) disas main
Dump of assembler code for function main:
0x0000000000001125 <+0>: push rbp
0x0000000000001126 <+1>: mov rbp,rsp
0x0000000000001129 <+4>: mov DWORD PTR [rbp-0x4],edi
0x000000000000112c <+7>: mov QWORD PTR [rbp-0x10],rsi
0x0000000000001130 <+11>: mov eax,0x0
0x0000000000001135 <+16>: pop rbp
0x0000000000001136 <+17>: ret
Now I want to disassemble at 0x0000000000001127, which is 1 byte into the first mov instruction:
(gdb) disas 0x0000000000001127
Dump of assembler code for function main:
0x0000000000001125 <+0>: push rbp
0x0000000000001126 <+1>: mov rbp,rsp
0x0000000000001129 <+4>: mov DWORD PTR [rbp-0x4],edi
0x000000000000112c <+7>: mov QWORD PTR [rbp-0x10],rsi
0x0000000000001130 <+11>: mov eax,0x0
0x0000000000001135 <+16>: pop rbp
0x0000000000001136 <+17>: ret
It still starts the disassembly at the top of main.
I've also tried things such as main+1, disas /r, etc. Did gdb's behavior change somehow? I thought perhaps it was related to this being a PIE binary, but when I recompile it with -no-pie I still have this problem for something so simple.
What is the correct syntax?
It still starts the disassembly at the top of main.
When you give disas a single argument, it finds the enclosing function, and disassembles that entire function. This has been the behavior since forever.
If you give disas two arguments instead, then it will disassemble just the given range:
(gdb) disas &main
Dump of assembler code for function main:
0x00000000000005fa <+0>: push %rbp
0x00000000000005fb <+1>: mov %rsp,%rbp
0x00000000000005fe <+4>: mov $0x0,%eax
0x0000000000000603 <+9>: pop %rbp
0x0000000000000604 <+10>: retq
End of assembler dump.
(gdb) disas &main+3,&main+11
Dump of assembler code from 0x5fd to 0x605:
0x00000000000005fd <main+3>: in $0xb8,%eax
0x00000000000005ff <main+5>: add %al,(%rax)
0x0000000000000601 <main+7>: add %al,(%rax)
0x0000000000000603 <main+9>: pop %rbp
0x0000000000000604 <main+10>: retq
End of assembler dump.
You could also use x/i:
(gdb) x/4i &main+3
0x5fd <main+3>: in $0xb8,%eax
0x5ff <main+5>: add %al,(%rax)
0x601 <main+7>: add %al,(%rax)
0x603 <main+9>: pop %rbp
When i execute the following commands i get different address of function()
(gdb) break function()
Breakpoint 1 at function() 0x804834a.
(gdb) print function()
Breakpoint 1 at function() 0x8048344.
Why there is difference in both address?
This output can't be correct, it would be if you did something as:
int func(void) {
int a = 10;
printf("%d\n", a);
return 1;
}
after loading it into the gdb:
(gdb) p func
$1 = {int (void)} 0x4016b0 <func>
(gdb) b func
Breakpoint 1 at 0x4016b6: file file.c, line 4.
(gdb) disassemble func
Dump of assembler code for function func:
0x004016b0 <+0>: push %ebp
0x004016b1 <+1>: mov %esp,%ebp
0x004016b3 <+3>: sub $0x28,%esp
0x004016b6 <+6>: movl $0xa,-0xc(%ebp)
0x004016bd <+13>: mov -0xc(%ebp),%eax
0x004016c0 <+16>: mov %eax,0x4(%esp)
0x004016c4 <+20>: movl $0x405064,(%esp)
0x004016cb <+27>: call 0x403678 <printf>
0x004016d0 <+32>: mov $0x1,%eax
0x004016d5 <+37>: leave
0x004016d6 <+38>: ret
End of assembler dump.
(gdb)
Here func points to the exact first instruction in the function, push %ebp, but when you setup a break point, gdb sets it after stack frame initialization instructions:
0x004016b0 <+0>: push %ebp
0x004016b1 <+1>: mov %esp,%ebp
0x004016b3 <+3>: sub $0x28,%esp
at where the instructions of the function actually begins:
=> 0x004016b6 <+6>: movl $0xa,-0xc(%ebp)
0x004016bd <+13>: mov -0xc(%ebp),%eax
0x004016c0 <+16>: mov %eax,0x4(%esp)
0x004016c4 <+20>: movl $0x405064,(%esp)
0x004016cb <+27>: call 0x403678 <printf>
0x004016d0 <+32>: mov $0x1,%eax
0x004016d5 <+37>: leave
0x004016d6 <+38>: ret
here this instruction:
movl $0xa,-0xc(%ebp) ; 0xa = 10
is this part:
int a = 10;
Gdb sets a breakpoint after function prologue, as before the things are properly set up it could not show the expected state like local variables, etc.
Break therefor sets breakpoint and prints address of first instruction after prologue, whereas print prints the address of actual first instruction in function.
You can set a breakpoint to actual first instruction by doing break *0x8048344, then observe the value of local variables there and after prologue.
(gdb) n
253 conf.log = log;
Like above,the next statement is conf.log = log;,how can I just disas that?
I tried simply disas,but gdb will disassembly all the current function(I don't need so much)...
(gdb) disas
Dump of assembler code for function ngx_init_cycle:
0x0000000000417c7c <ngx_init_cycle+0>: push %rbp
0x0000000000417c7d <ngx_init_cycle+1>: mov %rsp,%rbp
0x0000000000417c80 <ngx_init_cycle+4>: push %rbx
0x0000000000417c81 <ngx_init_cycle+5>: sub $0x258,%rsp
0x0000000000417c88 <ngx_init_cycle+12>: mov %rdi,-0x228(%rbp)
0x0000000000417c8f <ngx_init_cycle+19>: callq 0x42b2fc <ngx_timezone_update>
0x0000000000417c94 <ngx_init_cycle+24>: mov 0x2b00e5(%rip),%rax # 0x6c7d80 <ngx_cached_time>
0x0000000000417c9b <ngx_init_cycle+31>: mov %rax,-0x88(%rbp)
0x0000000000417ca2 <ngx_init_cycle+38>: mov -0x88(%rbp),%rax
0x0000000000417ca9 <ngx_init_cycle+45>: movq $0x0,(%rax)
0x0000000000417cb0 <ngx_init_cycle+52>: callq 0x4149e7 <ngx_time_update>
0x0000000000417cb5 <ngx_init_cycle+57>: mov -0x228(%rbp),%rax
0x0000000000417cbc <ngx_init_cycle+64>: mov 0x10(%rax),%rax
0x0000000000417cc0 <ngx_init_cycle+68>: mov %rax,-0x90(%rbp)
0x0000000000417cc7 <ngx_init_cycle+75>: mov -0x90(%rbp),%rsi
0x0000000000417cce <ngx_init_cycle+82>: mov $0x4000,%edi
0x0000000000417cd3 <ngx_init_cycle+87>: callq 0x405c6c <ngx_create_pool>
0x0000000000417cd8 <ngx_init_cycle+92>: mov %rax,-0x80(%rbp)
0x0000000000417cdc <ngx_init_cycle+96>: cmpq $0x0,-0x80(%rbp)
---Type <return> to continue, or q <return> to quit---q
UPDATE
(gdb) info line 98
Line 98 of "src/os/unix/ngx_process_cycle.c" starts at address 0x42f6f3 <ngx_master_process_cycle+31>
and ends at 0x42f704 <ngx_master_process_cycle+48>.
(gdb) disas 0x42f6f3,0x42f704
Dump of assembler code for function ngx_master_process_cycle:
0x000000000042f6d4 <ngx_master_process_cycle+0>: push %rbp
0x000000000042f6d5 <ngx_master_process_cycle+1>: mov %rsp,%rbp
0x000000000042f6d8 <ngx_master_process_cycle+4>: push %rbx
0x000000000042f6d9 <ngx_master_process_cycle+5>: sub $0x128,%rsp
0x000000000042f6e0 <ngx_master_process_cycle+12>: mov %rdi,-0x108(%rbp)
0x000000000042f6e7 <ngx_master_process_cycle+19>: lea -0xe0(%rbp),%rdi
0x000000000042f6ee <ngx_master_process_cycle+26>: callq 0x402988 <sigemptyset#plt>
0x000000000042f6f3 <ngx_master_process_cycle+31>: lea -0xe0(%rbp),%rdi
0x000000000042f6fa <ngx_master_process_cycle+38>: mov $0x11,%esi
0x000000000042f6ff <ngx_master_process_cycle+43>: callq 0x402878 <sigaddset#plt>
0x000000000042f704 <ngx_master_process_cycle+48>: lea -0xe0(%rbp),%rdi
0x000000000042f70b <ngx_master_process_cycle+55>: mov $0xe,%esi
0x000000000042f710 <ngx_master_process_cycle+60>: callq 0x402878 <sigaddset#plt>
0x000000000042f715 <ngx_master_process_cycle+65>: lea -0xe0(%rbp),%rdi
0x000000000042f71c <ngx_master_process_cycle+72>: mov $0x1d,%esi
0x000000000042f721 <ngx_master_process_cycle+77>: callq 0x402878 <sigaddset#plt>
0x000000000042f726 <ngx_master_process_cycle+82>: lea -0xe0(%rbp),%rdi
0x000000000042f72d <ngx_master_process_cycle+89>: mov $0x2,%esi
0x000000000042f732 <ngx_master_process_cycle+94>: callq 0x402878 <sigaddset#plt>
---Type <return> to continue, or q <return> to quit---
try something to the effect of:
(gdb) info line 12
Line 12 of "test.c" starts at address 0x4004f4 <main+24>
and ends at 0x4004fe <main+34>.
(gdb) disas 0x4004f4,0x4004fe
Dump of assembler code from 0x4004f4 to 0x4004fe:
0x00000000004004f4 <main+24>: mov $0x0,%eax
0x00000000004004f9 <main+29>: callq 0x4004d0 <bp3>
End of assembler dump.
Or:
(gdb) disas main+24,main+34
Dump of assembler code from 0x4004f4 to 0x4004fe:
0x00000000004004f4 <main+24>: mov $0x0,%eax
0x00000000004004f9 <main+29>: callq 0x4004d0 <bp3>
End of assembler dump.
not sure of a more automatic way offhand.
void outputString(const char *str) {
cout << "outputString(const char *str) : " << str << endl;
}
turns out to be
Dump of assembler code for function _Z12outputStringPKc:
0x004013ee <_Z12outputStringPKc+0>: push ebp
0x004013ef <_Z12outputStringPKc+1>: mov ebp,esp
0x004013f1 <_Z12outputStringPKc+3>: sub esp,0x8
0x004013f4 <_Z12outputStringPKc+6>: mov DWORD PTR [esp+4],0x443000
0x004013fc <_Z12outputStringPKc+14>: mov DWORD PTR [esp],0x4463c0
0x00401403 <_Z12outputStringPKc+21>: call 0x43f6e8 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>
0x00401408 <_Z12outputStringPKc+26>: mov edx,DWORD PTR [ebp+8]
0x0040140b <_Z12outputStringPKc+29>: mov DWORD PTR [esp+4],edx
0x0040140f <_Z12outputStringPKc+33>: mov DWORD PTR [esp],eax
0x00401412 <_Z12outputStringPKc+36>: call 0x43f6e8 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>
0x00401417 <_Z12outputStringPKc+41>: mov DWORD PTR [esp+4],0x43e4c8
0x0040141f <_Z12outputStringPKc+49>: mov DWORD PTR [esp],eax
0x00401422 <_Z12outputStringPKc+52>: call 0x42e170 <_ZNSolsEPFRSoS_E>
0x00401427 <_Z12outputStringPKc+57>: leave
0x00401428 <_Z12outputStringPKc+58>: ret
End of assembler dump.
All the disassemblies show only the manglinged function names,but its not eaiser for programmer to de-mangling and get the original function names with the bother to typing info symbol address for each mangling name met,so are there any methods that could make gdb show non-mangling function names on assembly model?
You could do maint demangle _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc at the (gdb) prompt.
The manual says:
`set print asm-demangle'
`set print asm-demangle on'
Print C++ names in their source form rather than their mangled
form, even in assembler code printouts such as instruction
disassemblies. The default is off.
Unfortunately, it doesn't appear to work:
(gdb) set print asm-demangle on
(gdb) disas
Dump of assembler code for function _Z12outputStringPKc:
0x00000000004009c4 <outputString(char const*)+0>: push %rbp
0x00000000004009c5 <outputString(char const*)+1>: mov %rsp,%rbp
0x00000000004009c8 <outputString(char const*)+4>: sub $0x10,%rsp
0x00000000004009cc <outputString(char const*)+8>: mov %rdi,-0x8(%rbp)
0x00000000004009d0 <outputString(char const*)+12>: mov $0x400bb0,%esi
0x00000000004009d5 <outputString(char const*)+17>: mov $0x6012a0,%edi
0x00000000004009da <outputString(char const*)+22>: callq 0x400798 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc#plt>
0x00000000004009df <outputString(char const*)+27>: mov %rax,%rdi
0x00000000004009e2 <outputString(char const*)+30>: mov -0x8(%rbp),%rsi
0x00000000004009e6 <outputString(char const*)+34>: callq 0x400798 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc#plt>
0x00000000004009eb <outputString(char const*)+39>: mov %rax,%rdi
0x00000000004009ee <outputString(char const*)+42>: mov $0x4007c8,%esi
0x00000000004009f3 <outputString(char const*)+47>: callq 0x4007b8 <_ZNSolsEPFRSoS_E#plt>
0x00000000004009f8 <outputString(char const*)+52>: leaveq
0x00000000004009f9 <outputString(char const*)+53>: retq
End of assembler dump.
The setting changed how the current function is printed, but not how the functions it calls are printed (which is what I assume you are after).
I think that is a bug in GDB, please file a bug in bugzilla.
Update:
The bug has been fixed in 2013. With GDB-10.0 the output is:
(gdb) disas 0x555555555169
Dump of assembler code for function _Z12outputStringPKc:
0x0000555555555169 <+0>: push %rbp
0x000055555555516a <+1>: mov %rsp,%rbp
0x000055555555516d <+4>: sub $0x10,%rsp
0x0000555555555171 <+8>: mov %rdi,-0x8(%rbp)
0x0000555555555175 <+12>: lea 0xe8c(%rip),%rax # 0x555555556008
0x000055555555517c <+19>: mov %rax,%rsi
0x000055555555517f <+22>: lea 0x2efa(%rip),%rax # 0x555555558080 <std::cout#GLIBCXX_3.4>
0x0000555555555186 <+29>: mov %rax,%rdi
0x0000555555555189 <+32>: callq 0x555555555040 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)#plt>
0x000055555555518e <+37>: mov %rax,%rdx
0x0000555555555191 <+40>: mov -0x8(%rbp),%rax
0x0000555555555195 <+44>: mov %rax,%rsi
0x0000555555555198 <+47>: mov %rdx,%rdi
0x000055555555519b <+50>: callq 0x555555555040 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)#plt>
0x00005555555551a0 <+55>: mov 0x2e29(%rip),%rdx # 0x555555557fd0
0x00005555555551a7 <+62>: mov %rdx,%rsi
0x00005555555551aa <+65>: mov %rax,%rdi
0x00005555555551ad <+68>: callq 0x555555555050 <std::ostream::operator<<(std::ostream& (*)(std::ostream&))#plt>
0x00005555555551b2 <+73>: nop
0x00005555555551b3 <+74>: leaveq
0x00005555555551b4 <+75>: retq
I don't remember ever finding an automatic way for gdb to do it. I always just copied and pasted the symbol and ran it through the Linux c++filt utility to demangle.
gdb show the original non-mangling function name on disassembly model ::
you have to do this steps every time whenever you are going to debug.
1. set print demangle on
2. set print asm-demangle on
Else you can create vim ~/.gdbinit file like ~/.vimrc file and set following steps so you no need to do every time on .
1 set print pretty on
2 set print demangle on
3 set print asm-demangle on