Disassemble in the middle of an instruction with gdb? - gdb

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

Related

GDB can't create a breakpoint [duplicate]

This question already has an answer here:
Cannot insert breakpoints. Addresses with low values
(1 answer)
Closed 4 years ago.
I am working on implementing a simple stack overflow, which I am examining with gdb. A problem I keep coming up with is gdb not accepting my breakpoints. My c code is quite simple:
void function(int a, int b, int c) {
...//stuff
}
void main() {
int x;
x = 0;
function(1,2,3);
x = 1;
printf("%d\n",x);
}
And i'm using gcc -m32 -fno-stack-protector -o example3test example3test.c to complie it.
I have tried just setting a simple breakpoint on the line <+42> just to test if it works.
(gdb) disass main
Dump of assembler code for function main:
0x000005d1 <+0>: lea 0x4(%esp),%ecx
0x000005d5 <+4>: and $0xfffffff0,%esp
0x000005d8 <+7>: pushl -0x4(%ecx)
0x000005db <+10>: push %ebp
0x000005dc <+11>: mov %esp,%ebp
0x000005de <+13>: push %ebx
0x000005df <+14>: push %ecx
0x000005e0 <+15>: sub $0x10,%esp
0x000005e3 <+18>: call 0x470 <__x86.get_pc_thunk.bx>
0x000005e8 <+23>: add $0x1a18,%ebx
0x000005ee <+29>: movl $0x0,-0xc(%ebp)
0x000005f5 <+36>: push $0x3
0x000005f7 <+38>: push $0x2
0x000005f9 <+40>: push $0x1
0x000005fb <+42>: call 0x5a0 <function>
0x00000600 <+47>: add $0xc,%esp
0x00000603 <+50>: movl $0x1,-0xc(%ebp)
0x0000060a <+57>: sub $0x8,%esp
0x0000060d <+60>: pushl -0xc(%ebp)
0x00000610 <+63>: lea -0x1950(%ebx),%eax
0x00000616 <+69>: push %eax
0x00000617 <+70>: call 0x400 <printf#plt>
0x0000061c <+75>: add $0x10,%esp
0x0000061f <+78>: nop
0x00000620 <+79>: lea -0x8(%ebp),%esp
0x00000623 <+82>: pop %ecx
0x00000624 <+83>: pop %ebx
0x00000625 <+84>: pop %ebp
0x00000626 <+85>: lea -0x4(%ecx),%esp
0x00000629 <+88>: ret
End of assembler dump.
(gdb) break *0x000005fb
Breakpoint 1 at 0x5fb
(gdb) run
Starting program: /home/jasmine/tutorials/smashingTheStackForFun/example3test
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x5fb
I'm lost as to why it won't accept this breakpoint. Most of the answers already on here involve not using the * or using wrong notation, from what I can see mine looks right, but I could be wrong.
I'm lost as to why it won't accept this breakpoint.
You have a position independent executable, which is relocated to a different address at runtime.
This will work:
(gdb) start
# GDB stops at main
(gdb) break *&main+42
(gdb) continue
See also this answer.

GDB Dis-Flavor set to Intel, but showing AT&T-style

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.

why there is difference in address of a function while using gdb break and gdb print?

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.

Can I disas a specific statement in gdb?

(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.

How do I make GCC instantiate a class instance with non-trivial const/dest?

I am implementing a profiler. I want to use the Constructor/Destructor idiom to keep track of when I enter/exit a function.
A rough outline of my code is as follows:
class Profile
{
Profile(void); //Start timing
~Profile(void); //Stop timer and log
};
//...
Game::Game(void) : m_Quit(false)
{
Profile p();
InitalizeModules();
//...
}
However, when I run it, the Constructor and destructor are not being called. Even when I disassemble, there are no references to Profile::Profile(). I understood that the standard specifies that an instance with a non-trivial constructor cannot be optimized out by the compiler.
There are no optimization flags on the command line of either the compiler or the linker.
I also tried specifying attribute((used)), but to no avail.
Here is the disassembly:
(gdb) disassemble Ztk::Game::Game
Dump of assembler code for function Ztk::Game::Game():
0x00000000004cd798 <+0>: push %rbp
0x00000000004cd799 <+1>: mov %rsp,%rbp
0x00000000004cd79c <+4>: push %r12
0x00000000004cd79e <+6>: push %rbx
0x00000000004cd79f <+7>: sub $0x30,%rsp
0x00000000004cd7a3 <+11>: mov %rdi,-0x38(%rbp)
0x00000000004cd7a7 <+15>: mov -0x38(%rbp),%rax
0x00000000004cd7ab <+19>: mov %rax,%rdi
0x00000000004cd7ae <+22>: callq 0x4cdc6a <Ztk::Highlander<Ztk::Game, int>::Highlander()>
/** CALL SHOULD BE HERE **/
0x00000000004cd7b3 <+27>: mov -0x38(%rbp),%rax
0x00000000004cd7b7 <+31>: movb $0x0,(%rax)
0x00000000004cd7ba <+34>: callq 0x4e59f0 <Ztk::InitializeModules()>
Indeed there is code generated and linked into the executable
(gdb) disassemble Ztk::Profile::Profile(void)
Dump of assembler code for function Ztk::Profile::Profile():
0x0000000000536668 <+0>: push %rbp
0x0000000000536669 <+1>: mov %rsp,%rbp
0x000000000053666c <+4>: sub $0x20,%rsp
0x0000000000536670 <+8>: mov %rdi,-0x18(%rbp)
0x0000000000536674 <+12>: mov 0x8(%rbp),%rax
0x0000000000536678 <+16>: mov %rax,-0x8(%rbp)
0x000000000053667c <+20>: mov -0x8(%rbp),%rax
0x0000000000536680 <+24>: mov %rax,%rsi
0x0000000000536683 <+27>: mov $0x802440,%edi
0x0000000000536688 <+32>: callq 0x5363ca <Ztk::Profiler::FindNode(void*)>
Profile p();
What you've done here is declared a function, called p, that returns an object of type Profile. What you want is this:
Profile p;