【问题标题】:two pieces of code, one works, one doesnt, why?两段代码,一段有效,一段无效,为什么?
【发布时间】:2013-12-15 15:44:49
【问题描述】:

我有两段代码,我认为它们的工作方式完全相同:

    if (ntohs(tcp_hdr->tcp_dport)==80) {
        char * parser = strtok(string,";;");
        while (parser != NULL){
            char parvar[100];
            strcpy(parvar, parser);
            if(parvar[0] == 'H' && parvar[1] == 'o' && parvar[2] == 's' && parvar[3] == 't') {
                char * substr = extract(parvar, 6, strlen(parvar));
                visited_hosts[hosts_counter] = substr;
                hosts_counter++;
            }
            parser = strtok(NULL, ";;");
        }

        bytes_sent += ((ip_hdr->ip_ttl)-40);
    }

    if (ntohs(tcp_hdr->tcp_sport)==80) {

        char * parser = strtok(string,";;");
        while (parser != NULL){
            char parvar[100];
            strcpy(parvar, parser);
            if(parvar[0] == 'L' && parvar[1] == 'o' && parvar[2] == 'c' && parvar[3] == 'a') {
                char * substr = extract(parvar, 10, strlen(parvar));
                visited_pages[pages_counter] = substr;
                pages_counter++;
            }
            parser = strtok(NULL, ";;");
        }
        bytes_received += ((ip_hdr->ip_ttl)-40);            
    }

我有 while(1) 侦听器,第一段代码工作正常,但第二段代码在完成任务后因分段错误退出循环。我无法使用 gdb,因为我正在使用 QEMU 来测试我的解决方案。你们知道可能是什么问题吗,或者我还能用什么来调试 QEMU 中的 c 代码?

【问题讨论】:

  • 当你制作“strcpy(parvar, parser);” parser 在两个选项中是否具有相同的值?

标签: c parsing segmentation-fault qemu


【解决方案1】:

恭喜,你刚刚中了固定限制陷阱:

您在堆栈上分配一个 100 字节的数组,然后将一个 unknown 大小的字符串复制到其中(使用 strcpy())。现在,当解析器是一个长度超过 100 字节的字符串时,strcpy() 继续写入数组末尾之后,覆盖堆栈上的重要数据,包括函数返回地址。这就是为什么当你的函数试图返回时你的程序崩溃的原因——它试图跳转到一个不存在的地址。

我的建议是:不惜一切代价避免使用固定大小的缓冲区。不惜一切代价避免任何固定限制。唯一的例外是您可以证明未来的使用将永远无法超过限制。因为,每当你使用一个固定的限制时,我可以向你保证,总有一天它会被超过并咬住你。找到这样一个错误来修复它比第一次正确地修复它要昂贵得多

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 2010-09-17
    相关资源
    最近更新 更多