我有以下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
不幸的是,我似乎无法理解它。
非常感谢任何见解。
非常感谢,
感谢Kerrick SB,我已经更进了一步。
现在是输出:
eamorr@Compaq6000:/mnt/eamorr/workspace/ByteCache/Debug# ./ByteCache 361457034 len:872, ptr:6304000 46267872 len:12, ptr:-92779411 Segmentation fault
我可以看到负面的ptr?我不知道这是怎么回事。我甚至改变了ptr来键入unsigned int。
答案 0 :(得分:4)
我认为你不想做ptr =&堆,你想要ptr = heap。 malloc返回一个指向它分配的内存的指针,这似乎是你在回调中试图引用的内容。
你只想使用&得到某事的地址。例如: MyStructure MyVariable; void * pAPointer =& MyVariable;
如果你是malloc-ing,你会得到一个返回的指针: MyStructure * pPointerToStructure = malloc(sizeof(MyStructure));
使用&在pPointerToStructure上为您提供指向指针的指针,而不是来自malloc调用的已分配内存
答案 1 :(得分:3)
memcpy
将void指针作为参数,但是你将第二个参数转换为char
。解决这个问题:
memcpy(ptr, (const void *) payload, len * sizeof(u_char));
就此而言,为什么不将ptr
声明为void**
(即说static void ** ptr;
)?
另外,为什么所有的过度铸造?您无需转换malloc()
或payload =
作业的结果,因为它们已经是正确的类型。最后,len
可能属于size_t
类型,因为它是一种大小类型(即无符号)。