Nhull Nhull - 1 year ago 147
C Question

GDB breakpoint in main() cannot access memory

My question is why when i set a breakpoint in main() with GDB i receive the error

<0xffffffffffffe550: Cannot access memory at address 0xffffffffffffe550>

I wanted to set a breakpoint in main() so i could examine the memory in the stack. My disassembled code is this:

0x00000000004008e8 <+0>: push %rbp
0x00000000004008e9 <+1>: mov %rsp,%rbp
0x00000000004008ec <+4>: add $0xffffffffffffff80,%rsp
0x00000000004008f0 <+8>: mov %edi,-0x74(%rbp)
0x00000000004008f3 <+11>: mov %rsi,-0x80(%rbp)
=> 0x00000000004008f7 <+15>: movl $0x1,-0x4(%rbp)
0x00000000004008fe <+22>: cmpl $0x1,-0x74(%rbp)
0x0000000000400902 <+26>: jle 0x400920 <main+56>
0x0000000000400904 <+28>: mov -0x80(%rbp),%rax
0x0000000000400908 <+32>: add $0x8,%rax
0x000000000040090c <+36>: mov (%rax),%rdx
0x000000000040090f <+39>: lea -0x70(%rbp),%rax
0x0000000000400913 <+43>: mov %rdx,%rsi
0x0000000000400916 <+46>: mov %rax,%rdi
0x0000000000400919 <+49>: callq 0x400670 <strcpy@plt>
0x000000000040091e <+54>: jmp 0x400924 <main+60>
0x0000000000400920 <+56>: movb $0x0,-0x70(%rbp)
0x0000000000400924 <+60>: callq 0x4006a0 <getuid@plt>
0x0000000000400929 <+65>: mov %eax,-0x8(%rbp)
0x000000000040092c <+68>: mov $0x0,%esi
0x0000000000400931 <+73>: mov $0x400c6e,%edi
0x0000000000400936 <+78>: mov $0x0,%eax
0x000000000040093b <+83>: callq 0x400720 <open@plt>
0x0000000000400940 <+88>: mov %eax,-0xc(%rbp)
0x0000000000400943 <+91>: cmpl $0xffffffff,-0xc(%rbp)
0x0000000000400947 <+95>: jne 0x40096b <main+131>
0x0000000000400949 <+97>: mov $0x400c80,%edi
0x000000000040094e <+102>: callq 0x400856 <fatal>
0x0000000000400953 <+107>: jmp 0x40096b <main+131>
0x0000000000400955 <+109>: lea -0x70(%rbp),%rdx
0x0000000000400959 <+113>: mov -0x8(%rbp),%ecx
0x000000000040095c <+116>: mov -0xc(%rbp),%eax
0x000000000040095f <+119>: mov %ecx,%esi
0x0000000000400961 <+121>: mov %eax,%edi
0x0000000000400963 <+123>: callq 0x40098c <print_notes>
0x0000000000400968 <+128>: mov %eax,-0x4(%rbp)
0x000000000040096b <+131>: cmpl $0x0,-0x4(%rbp)
0x000000000040096f <+135>: jne 0x400955 <main+109>
0x0000000000400971 <+137>: mov $0x400cb0,%edi
0x0000000000400976 <+142>: callq 0x400680 <puts@plt>
0x000000000040097b <+147>: mov -0xc(%rbp),%eax
0x000000000040097e <+150>: mov %eax,%edi
0x0000000000400980 <+152>: callq 0x4006e0 <close@plt>
0x0000000000400985 <+157>: mov $0x0,%eax
0x000000000040098a <+162>: leaveq
0x000000000040098b <+163>: retq

And the code until my main is this:

#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "usefullfuncs.h"

#define FILENAME "/var/notes"

int print_notes(int, int, char *);
int find_user_note(int,int);
int search_note(char *, char *);

int main(int argc, char *argv[]){
int userid,printing=1,fd;
char searchstring[100];

searchstring[0] = 0;

userid = getuid();

if(fd == -1)
fatal("in main() while opening file for reading");

printing = print_notes(fd,userid,searchstring);
printf("-------[ end of note data ]-------\n");

int print_notes(int fd,int uid,char *searchstring){
int note_lenght;
char note_buffer[100];

note_lenght = find_user_note(fd,uid);

if(note_lenght == -1)
return 0;

note_buffer[note_lenght] = 0;

return 1;

int find_user_note(int fd,int user_uid){
int note_uid=-1;
unsigned char byte;
int lenght;

while(note_uid != user_uid){
return -1;
return -1;

byte = lenght = 0;

while(byte != '\n'){
return -1;


printf("[DEBUG] found a %d byte note for user id %d\n",lenght,note_uid);
return lenght;

int search_note(char *note, char *keyword){
int i,keyword_lenght,match=0;

keyword_lenght = strlen(keyword);

if(keyword_lenght == 0)
return 1;

for(i=0;i < strlen(note);i++){
if(note[i] == keyword[match])
if(note[i] == keyword[0])
match = 1;
match = 0;
if(match == keyword_lenght)
return 1;
return 0;

Thanks in advance.

Answer Source
(gdb) x/24s $esp
0xffffffffffffe550: <error: Cannot access memory at address 0xffffffffffffe550>

On an x86-64 target, $rsp should be used. Using $esp will lead to incorrect results.

$esp is taken from the bottom 32 bits of the 64-bit $rsp register, and gdb treats it as type int32_t. $rsp in your example was probably 0x7fffffffe550. Gdb's x command, which wants to use a 64-bit address, will take the bottom 32 bits of $rsp, 0xffffe550, and sign-extend that to 0xffffffffffffe550. That's almost certainly an invalid address; typical user-space addresses on Linux don't go above 0x7ffffffff000 or so.

Try x/24s $rsp. If you're trying to follow exercises out of an old book, you may be able to duplicate their 32-bit examples by giving gcc the -m32 option, if it supports it. Then you can use $esp.