My question is on instruction pointer. The definition of instruction pointer is "Instruction pointer is a register that holds the memory address of the instruction to be executed next". However when a linux application crash, I am seeing the instruction pointer is pointing to the current executing instruction(not the next instruction). Following is an example code which is written to crash(SIGSEGV).
#include <string.h>
int main()
{
char *ptr=NULL;
strcpy(ptr, "abcd"); //This line should crash
}
A portion of the disassembly of main function is given below;
00000000004004ed <main>:
#include <stdio.h>
#include <string.h>
int main()
{
4004ed: 55 push %rbp
4004ee: 48 89 e5 mov %rsp,%rbp
char *ptr=NULL;
4004f1: 48 c7 45 f8 00 00 00 movq $0x0,-0x8(%rbp)
4004f8: 00
strcpy(ptr, "abcd");
4004f9: 48 8b 45 f8 mov -0x8(%rbp),%rax
4004fd: c7 00 61 62 63 64 movl $0x64636261,(%rax)
400503: c6 40 04 00 movb $0x0,0x4(%rax)
}
400507: 5d pop %rbp
400508: c3 retq
400509: 0f 1f 80 00 00 00 00 nopl 0x0(%rax)
In gdb , from the core dumped file I have printed the $rip(instruction pointer)
(gdb) print $rip
$1 = (void (*)()) 0x4004fd <main+16>
My understanding is that the assembly instruction movl $0x64636261,(%rax)
at address 0x4004fd
is crashing as this code tries to write to the NULL
address pointed by $rax
. My question is if instruction pointer points to the next instruction to be executed, how the $rip in gdb was printed 0x4004fd
does that had to be printed 400503
?