c - memcpy 上的段错误

标签 c segmentation-fault memcpy

<分区>

完整代码在

http://docs.google.com/file/d/0B09y_TWqTtwlaHNjdjYybHVIcjA/edit?usp=sharing

    char data[]="just for a try";
    u_char *packet=(u_char *)malloc(28+sizeof(data));
     ...
     ...


    u_char *udp_data=(u_char *)malloc(8+sizeof(data));
    if(udp_data == NULL )
            perror("allocating space for udp_data fails\n");
    memcpy(udp_data, &udp, sizeof(udp));
    memcpy(udp_data+8, data, sizeof(data));
    udp.check = in_cksum_udp(ip.ip_src.s_addr, ip.ip_dst.s_addr, (unsigned short *)udp_data, sizeof(udp)+sizeof(data)); // if I comment this line, no segmentation fault!
    free(udp_data);
    udp_data=NULL;

    // I get segmentation fault on the next line:
    memcpy(packet + 20, &udp, sizeof(udp));

问题是 cksum_udp() 函数 错误是

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400a2b in run (arg=0x0) at raw_udp_client.c:115
115     memcpy(packet + 20, &udp, sizeof(udp));

核心转储 https://docs.google.com/file/d/0B09y_TWqTtwldFI5UGdfc01RU28/edit?usp=sharing 在 in_cksum_udp() 之前

ip = {ip_hl = 5, ip_v = 4, ip_tos = 0 '\000', ip_len = 10752, ip_id = 0, 
ip_off = 0, ip_ttl = 64 '@', ip_p = 17 '\021', ip_sum = 32808, ip_src = {
s_addr = 1825136778}, ip_dst = {s_addr = 376725642}}
udp = {source = 51377, dest = 125, len = 5632, check = 0}
sd = 0
on = 1
sin = {sin_family = 1, sin_port = 0, sin_addr = {s_addr = 0}, 
sin_zero = "ݲ\360\000\000\000\000"}
packet = 0x602010 "E"
data = "I'm not here!"
udp_data = 0x602050 "\261\310}"

在 in_cksum_udp() 之后

ip = {ip_hl = 0, ip_v = 0, ip_tos = 0 '\000', ip_len = 0, ip_id = 0, 
ip_off = 0, ip_ttl = 0 '\000', ip_p = 0 '\000', ip_sum = 0, ip_src = {
  s_addr = 0}, ip_dst = {s_addr = 0}}
udp = {source = 0, dest = 0, len = 0, check = 4842}
sd = 0
on = 0
sin = {sin_family = 0, sin_port = 0, sin_addr = {s_addr = 0}, 
sin_zero = "\000\000\000\000\000\000\000"}
packet = 0x0
data = '\000' <repeats 13 times>
udp_data = 0x0

in_cksum_udp() 函数如下,我没有发现任何问题:

struct psd_udp {
    struct in_addr src;
    struct in_addr dst;
    unsigned char pad;
    unsigned char proto;
    unsigned short udp_len;
    struct udphdr udp;
};

unsigned short in_cksum(unsigned short *addr, int len)
{
    int nleft = len;
    int sum = 0;
    unsigned short *w = addr;
    unsigned short answer = 0;

    while (nleft > 1) {
            sum += *w++;
            nleft -= 2;
    }

    if (nleft == 1) {
            *(unsigned char *) (&answer) = *(unsigned char *) w;
            sum += answer;
    }

    sum = (sum >> 16) + (sum & 0xFFFF);
    sum += (sum >> 16);
    answer = ~sum;
    return (answer);
}


unsigned short in_cksum_udp(int src, int dst, unsigned short *addr, int len)
{
    struct psd_udp buf;

    memset(&buf, 0, sizeof(buf));
    buf.src.s_addr = src;
    buf.dst.s_addr = dst;
    buf.pad = 0;
    buf.proto = IPPROTO_UDP;
    buf.udp_len = htons(len);
    memcpy(&(buf.udp), addr, len);
    return in_cksum((unsigned short *)&buf, 12 + len);
}

看来函数与指针包指向的内存无关 什么是潜在问题?

最佳答案

在函数 in_csum_udp 中,这一行:

memcpy(&(buf.udp), addr, len);

正在将 sizeof(struct udphdr) + sizeof(data) 字节复制到 buf.udp,即 struct udphdr。由于这是结构的最后一个元素,因此堆栈已损坏。

关于c - memcpy 上的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15494717/

相关文章:

c - 选择结构成员并更改其内容的函数

c - 需要关于我的斐波那契程序的解释

c++ - 使用克隆(): segmentation fault

c++ - 创建指向 unsigned char[] 的指针并将其传递给 sf::SoundBuffer::loadFromMemory

c++ - 复制到一个更大的变量

无法在C程序中拆分数组

c - 阿尔萨 API : how to use mmap in c?

sql - 如何使用 SQLExecDirect?

c++ - 使用 vector 的 C++ 中的段错误

c++ - Ubuntu 中 getline 的段错误