user2320249
user2320249

Reputation: 1

Segfault occurs, GDB breaks on line, but running line after segfault shows no violation

I have a program which is segfaulting at a specific line:

uint64_t smaller_num = *(uint64_t*)(smaller_base+index);

GDB successfully catches the segfault allowing me to debug the issue. However, if I run the line from the GDB prompt, no memory access violation occurs:

(gdb) p smaller_num = *(uint64_t*)(smaller_base+index)

Can anyone provide some suggestions on how to debug this issue? I am at a loss of words and ideas because I verified that the memory at smaller_base+index exists. Can it be something with the casting?

Thanks in advance.

EDIT: providing more code but it really is that simple. I have heavily edited code to show the point of the indexing.

uint64_t ** find_difference(unsigned char * larger_base,
                              uint64_t size,
                              unsigned char * smaller_base,
                              uint64_t tmap_size)
{
    uint64_t len = size < tmap_size?size:tmap_size;
    uint64_t index=0;
    while(index<len)
    {
            uint64_t larger_num = *(uint64_t*)(larger_base+index);
            uint64_t smaller_num = *(uint64_t*)(smaller_base+index);
            if(larger_num > smaller_num)
            {
                ... do stuff
            }
            index++;
    }

    ...
}

Edit#2: Now that I am thinking about it, is it poissible that the pointer dereference goes beyond len? It was my understanding that x86 numbers are stored from high to low addresses. Thus in memory, a number 0x01020304 is stored as 0x04 0x03 0x02 0x01. Is this correct? If this is not true, the deference would go beyond the end of the buffer. However, in GDB I verified the address is accessible.

Upvotes: 0

Views: 232

Answers (2)

scottt
scottt

Reputation: 7228

Your original pointer arithmetic added index to a (unsigned char *) before casting it to uint64_t causing an unaligned memory load, i.e. trying to dereference an (uint64_t *) from an address that is not a multiple of 8. This works in the debugger but causes a SEGFAULT in your program.

Upvotes: 0

Nikolai
Nikolai

Reputation: 1335

I do not know how you use find_difference() function and what values of parameters passed to the function, but I suspect that your pointer arithmetic is wrong.

You are incrementing large_base and smaller_base by 1 and casting resulting address as u64*. If size is in bytes, then you should check that large_base+index+8 < size.

Upvotes: 1

Related Questions