C: Пожалуйста, помогите мне отладить эту ошибку сегмента, связанную с памятью - PullRequest
0 голосов
/ 28 июля 2011

У меня есть следующий код C:

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;
}

А вот функция обратного вызова, которая вызывается время от времени:

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;
}

Вот мой дамп из 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 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

К сожалению, я не вижу в этом особого смысла.

Любое понимание высоко ценится.

Заранее большое спасибо,


Благодаря Керрику С.Б. я продвинулся еще на один шаг.

Вот теперь вывод:

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

Я вижу отрицательный результат?Я понятия не имею, как это возможно.Я даже изменил ptr на тип unsigned int.

Ответы [ 2 ]

4 голосов
/ 28 июля 2011

Я не думаю, что вы хотите сделать ptr = & heap, вы хотите, чтобы ptr = heap.malloc возвращает указатель на выделенную память, что, по-видимому, является тем, на что вы пытаетесь сослаться в обратном вызове.

Вы хотите использовать только &, чтобы получить адрес чего-либо.Например: MyStructure MyVariable;void * pAPointer = & MyVariable;

Если вы используете неправильное указание, вы получите указатель, возвращенный так: MyStructure * pPointerToStructure = malloc (sizeof (MyStructure));

для использования & on pPointerToStructureдает указатель на указатель, а не на выделенную память из вызова malloc

3 голосов
/ 28 июля 2011

memcpy принимает пустые указатели в качестве аргументов, но вы приводите второй аргумент к char.Чтобы исправить это:

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

В этом отношении, почему бы вам не объявить ptr как void** (т.е. сказать static void ** ptr;)?

Кроме того, почему все чрезмерноеКастинг?Вам не нужно приводить результат присваивания malloc() или payload =, поскольку они уже имеют правильный тип.Наконец, len, вероятно, должен иметь тип size_t, потому что это тип размера (то есть без знака).

...