开发者

C: Please help me debug this memory-related seg fault

开发者 https://www.devze.com 2023-03-23 06:46 出处:网络
I have the following C code: static void* heap; static unsigned int ptr; int main(void) { ... heap=(void*)malloc(10000*sizeof(char));

I have the following C code:

static void* heap;
static unsigned int ptr;

int main(void) {
    ...
    heap=(void*)malloc(10000*sizeof(char));
    ptr=&heap;

    /*Actual sniffing*/
    pcap_loop(handle,-1,callback,NULL);

    return 0;
}

And here is the callback function that gets called every once in a while:

void callback(u_char *useless,const struct pcap_pkthdr* header,const u_char* packet){
   const u_char *payload;
   ...
   payload = (u_char *)(packet + size_ethernet + size_ip + size_tcp);

   unsigned int hash=DJBHash(payload,strlen(payload));
   printf("%u\n",hash);   //ok

   int len=strlen(payload)*sizeof(u_char);

   printf("len:%d, ptr:%d\n",len,ptr);   //ok

   memcpy(ptr,(char)payload,len*sizeof(u_char));   //I'm getting a seg fault here!
   ptr+=len;
}

Here is my dump from valgrind:

==8687== Memcheck, a memory error detector
==8687== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==8687== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==8687== Command: ./ByteCache
==8687== 
==8687== Syscall param socketcall.setsockopt(optval) points to uninitialised byte(s)
==8687==    at 0x514D12A: setsockopt (syscall-template.S:82)
==8687==    by 0x4E34991: ??? (in /usr/lib/libpcap.so.1.1.1)
==8687==    by 0x4E34AB2: ??? (in /usr/lib/libpcap.so.1.1.1)
==8687==    by 0x401A3F: main (ByteCache.c:123)
==8687==  Address 0x7fefffb42 is on thread 1's stack
==8687== 
2912431451
len:12, ptr:6304012
==8687== Invalid read of size 8
==8687==    at 0x4C2A337: memcpy (mc_replace_strmem.c:635)
==8687==    by 0x4018CB: callback (ByteCache.c:77)
==8687==    by 0x4E34E24: ??? (in /usr/lib/libpcap.so.1.1.1)
==8687==    by 0x4E3A818: pcap_loop (in /usr/lib/libpcap.so.1.1.1)
==8687==    by 0x401AB4: main (ByteCache.c:133)
==8687==  Address 0x80 is not stack'd, malloc'd or (recently) free'd
==8687== 
==8687== 
==8687== Process terminating with default action of signal 11 (SIGSEGV)
==8687==  Access not within mapped region at address 0x80
==8687==    at 0x4C2A337: memcpy (mc_replace_strmem.c:635)
==8687==    by 0x4018CB: callback (ByteCache.c:77)
==8687==    by 0x4E34E24: ??? (in /usr/lib/libpcap.so.1.1.1)
==8687==    by 0x4E3A818: pcap_loop (in /usr/lib/libpcap.so.1.1.1)
==8687==    by 0x401AB4: main (ByteCache.c:133)
==8687==  If you believe this happened as a result of a stack
==8687==  overflow in your program's main thread (unlikely but
==8687==  possible), you can try to increase the size of the
==8687==  main thread stack using the --main-stacksize= flag.
==8687==  The main thread stack size used in this run was 8388608.
==8687== 
==8687== HEAP SUMMARY:
==8687==     in use at exit: 22,711 bytes in 11 blocks
==8687==   total heap usage: 41 allocs, 30 frees, 38,352 bytes allocated
==8687== 
==8687== LEAK SUMMARY:
==8687==    definitely lost: 0 bytes in 0 blocks
==8687==    indirectly lost: 0 bytes in 0 blocks
==8687==      possibly lost: 0 bytes in 0 blocks
==8687==    still reachable: 22,711 bytes in 11 blocks
==8687==         suppressed: 0 bytes 开发者_StackOverflow中文版in 0 blocks
==8687== Reachable blocks (those to which a pointer was found) are not shown.
==8687== To see them, rerun with: --leak-check=full --show-reachable=yes
==8687== 
==8687== For counts of detected and suppressed errors, rerun with: -v
==8687== Use --track-origins=yes to see where uninitialised values come from
==8687== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4)
Segmentation fault

Unfortunately, I can't seem to make much sense of it.

Any insight greatly appreciated.

Many thanks in advance,


Thanks to Kerrick SB, I've gotten one step further.

Here now is the output:

eamorr@Compaq6000:/mnt/eamorr/workspace/ByteCache/Debug# ./ByteCache
361457034
len:872, ptr:6304000
46267872
len:12, ptr:-92779411
Segmentation fault

I can see a negative ptr? I have no idea how this is possible. I've even changed ptr to type unsigned int.


I don't think you want to do ptr = &heap, you want ptr = heap. malloc returns a pointer to the memory it allocated, which seems to be what you're trying to refer to in your callback.

You only want to use the & to get the address of something. For example: MyStructure MyVariable; void* pAPointer = &MyVariable;

If you're malloc-ing you get a pointer returned so: MyStructure *pPointerToStructure = malloc(sizeof(MyStructure));

to use the & on pPointerToStructure gives you the pointer to the pointer, not to the allocated memory from the malloc call


memcpy takes void pointers as its arguments, yet you're casting the second argument to a char. To fix this:

memcpy(ptr, (const void *) payload, len * sizeof(u_char));

For that matter, why don't you declare ptr as void** (i.e. say static void ** ptr;)?

Also, why all the excessive casting? You don't need to cast the result of malloc() or of the payload = assignment, as they're already the correct type. Finally, len should probably be of type size_t, because it's a size type (i.e. unsigned).

0

精彩评论

暂无评论...
验证码 换一张
取 消