新的没有分配足够的内存?
好吧,我直接从网络上获取数据包并从中提取 TCP 流。
简而言之,这意味着剥离各种标头(例如,eth->IP->TCP->流数据)。
在我最终完成所有标头后调用的函数中,我遇到了一个奇怪的错误。
/*Meta is a pointer to the IP header, pkt is a pointer to the TCP header*/
virtual const u_char* processPacket(const u_char* pkt, const u_char* meta) {
//Extract IP info from meta.
iphdr* metaHdr = (iphdr*)meta;
//Form TCP header from the current offset, hdr.
const tcphdr* hdr = (const tcphdr*)pkt;
//Do pointer math to figure out the size of the stream data.
u_int32_t len = ntohs(metaHdr->tot_len) - metaHdr->ihl*4 - hdr->doff*4;
if(len > 0)
{
//Store TCP stream data in a queue, mapped to it's IP source.
TCPStream* stream = new TCPStream();
stream->seqNumber = ntohl(hdr->seq);
stream->streamData = new u_char(len);
//memcpy(stream->streamData, offset(pkt), len);
for(u_int32_t i = 0; i < len; i++)
{
printf("k%i-%i",len, i); //Used to figure out when the segfault occurs.
stream->streamData[i] = offset(pkt)[i]; //Offset returns a pointer to the data under the TCP header
}
//streams[metaHdr->saddr].push(stream);
}
return offset(pkt);
};
TCP 流只是一个 u_int32_t
和一个 u_char*
指向数据包数据的副本。 所以,当我使用 memcpy 时,它出现了段错误。
显然,要么我的指针无效,要么我搞乱了我的长度。
在此特定数据包的情况下,数据长度为 1380 字节(由 Wireshark 确认),因此 len 计算正确。
好吧,所以我的指针一定搞砸了(但不是 NULL)。我做了以下实验:
stream->streamData[0] = offset(pkt)[0]; //Works
stream->streamData[0] = offset(pkt)[len]; //Works, odd.
stream->streamData[len] = offset(pkt)[0]; //Fails, scary
stream->streamData[len] = offset(pkt)[len]; //Fails
因此,当对streamData(具体来说是索引1236)解除引用太远时,我会出现段错误! 但是streamData被实例化为:
stream->streamData = new u_char(len);
我在i=0处开始迭代streamData,所以我不会跳过一堆数据。 StreamData 是 u_char*
,而 offset(pkt)
是 u_char*
所以我不会弄乱我的类型。
在成功迭代 3000 多个其他数据包后,此操作在特定数据包处失败。转储文件有 27 兆,我有 4 GB 内存,所以我不认为我用完了或者什么......所以我被迫得出结论 new 没有分配足够的内存,但为什么?
Well, I'm taking packets straight off the wire and extracting TCP streams from them.
In the short, this means stripping off the various headers (eg, eth->IP->TCP->stream data).
In the function that is called when I've finally gotten through all the headers, I am experiencing a strange error.
/*Meta is a pointer to the IP header, pkt is a pointer to the TCP header*/
virtual const u_char* processPacket(const u_char* pkt, const u_char* meta) {
//Extract IP info from meta.
iphdr* metaHdr = (iphdr*)meta;
//Form TCP header from the current offset, hdr.
const tcphdr* hdr = (const tcphdr*)pkt;
//Do pointer math to figure out the size of the stream data.
u_int32_t len = ntohs(metaHdr->tot_len) - metaHdr->ihl*4 - hdr->doff*4;
if(len > 0)
{
//Store TCP stream data in a queue, mapped to it's IP source.
TCPStream* stream = new TCPStream();
stream->seqNumber = ntohl(hdr->seq);
stream->streamData = new u_char(len);
//memcpy(stream->streamData, offset(pkt), len);
for(u_int32_t i = 0; i < len; i++)
{
printf("k%i-%i",len, i); //Used to figure out when the segfault occurs.
stream->streamData[i] = offset(pkt)[i]; //Offset returns a pointer to the data under the TCP header
}
//streams[metaHdr->saddr].push(stream);
}
return offset(pkt);
};
TCP stream is simply a u_int32_t
and a u_char*
pointing to a copy of the packet's data.
So, when I was using memcpy it segfaulted.
Obviously, either my pointers were invalid, or I was messing up my length.
In this particular packet's case, the length of the data is 1380 bytes (confirmed by Wireshark), so len is correctly computed.
Ok, so I must have my pointers messed up (but not NULL). I did the following experiment:
stream->streamData[0] = offset(pkt)[0]; //Works
stream->streamData[0] = offset(pkt)[len]; //Works, odd.
stream->streamData[len] = offset(pkt)[0]; //Fails, scary
stream->streamData[len] = offset(pkt)[len]; //Fails
So, I segfault when dereferencing too far into streamData (index 1236 to be specific)!
But streamData is instantiated as:
stream->streamData = new u_char(len);
I start iterating through streamData at i=0, so I'm not skipping a bunch of my data.
streamData is u_char*
and offset(pkt)
is u_char*
so I'm not messing up my types.
This fails at a particular packet, after successfully iterating through 3000+ other packets. The dump file is 27 megs, and I've got 4 gigs of ram, so I don't think I'm running out or anything... So I'm forced to conclude that new is not allocating enough memory, but why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这会分配一个字符,初始化为
len
。要分配数组,请使用:
并且无论在何处释放它:
编辑:
即使数组已正确分配,这也将是未定义的行为。要访问的有效索引为 0 到
len
不包含。This allocates a single character, intialized to
len
.To allocate an array, use:
And where-ever you deallocate it:
Edit:
That would be undefined behavior even if the array was allocated correctly. Valid indexes to access are 0 to
len
not inclusive.