【问题标题】:Valgrind giving errors with getline()Valgrind 使用 getline() 给出错误
【发布时间】:2011-07-02 11:10:43
【问题描述】:

我有一个调用getline() 的函数,它从标准文本文件中读取行。这些行以\r\n 结尾,因为这是规范所要求的,因为它是 VCARD 文件的“互联网标准”。

无论如何,我在 OpenSUSE 11.3 上使用最新的 GCC 和 Valgrind 版本通过 Valgrind 运行这个婴儿;没有错误。但是,由于与此问题无关的原因,我将发行版切换到 Back Track 4(基于 Ubuntu),现在我收到大量 Valgrind 错误:

    ==21536== Conditional jump or move depends on uninitialised value(s)
==21536==    at 0x40164A1: (within /lib/ld-2.11.1.so)
==21536==    by 0x4007C04: (within /lib/ld-2.11.1.so)
==21536==    by 0x4002A2C: (within /lib/ld-2.11.1.so)
==21536==    by 0x4014206: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000C6C: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000856: (within /lib/ld-2.11.1.so)
==21536==
==21536== Conditional jump or move depends on uninitialised value(s)
==21536==    at 0x40164AC: (within /lib/ld-2.11.1.so)
==21536==    by 0x4007C04: (within /lib/ld-2.11.1.so)
==21536==    by 0x4002A2C: (within /lib/ld-2.11.1.so)
==21536==    by 0x4014206: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000C6C: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000856: (within /lib/ld-2.11.1.so)
--21536-- Warning: DWARF2 CFI reader: unhandled DW_OP_ opcode 0x55
--21536-- Warning: DWARF2 CFI reader: unhandled DW_OP_ opcode 0x55
--21536-- DWARF2 CFI reader: unhandled CFI instruction 0:10
--21536-- DWARF2 CFI reader: unhandled CFI instruction 0:10
--21536-- DWARF2 CFI reader: unhandled CFI instruction 0:10
--21536-- DWARF2 CFI reader: unhandled CFI instruction 0:10
--21536-- DWARF2 CFI reader: unhandled CFI instruction 0:10
--21536-- DWARF2 CFI reader: unhandled CFI instruction 0:10
--21536-- DWARF2 CFI reader: unhandled CFI instruction 0:10
==21536==
==21536== Conditional jump or move depends on uninitialised value(s)
==21536==    at 0x400B217: (within /lib/ld-2.11.1.so)
==21536==    by 0x40031D0: (within /lib/ld-2.11.1.so)
==21536==    by 0x4014206: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000C6C: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000856: (within /lib/ld-2.11.1.so)
==21536==
==21536== Conditional jump or move depends on uninitialised value(s)
==21536==    at 0x400AF0F: (within /lib/ld-2.11.1.so)
==21536==    by 0x40031D0: (within /lib/ld-2.11.1.so)
==21536==    by 0x4014206: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000C6C: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000856: (within /lib/ld-2.11.1.so)
==21536==
==21536== Conditional jump or move depends on uninitialised value(s)
==21536==    at 0x400B27A: (within /lib/ld-2.11.1.so)
==21536==    by 0x40031D0: (within /lib/ld-2.11.1.so)
==21536==    by 0x4014206: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000C6C: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000856: (within /lib/ld-2.11.1.so)
==21536==
==21536== Conditional jump or move depends on uninitialised value(s)
==21536==    at 0x400A5DE: (within /lib/ld-2.11.1.so)
==21536==    by 0x40030FE: (within /lib/ld-2.11.1.so)
==21536==    by 0x4014206: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000C6C: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000856: (within /lib/ld-2.11.1.so)
==21536==
==21536== Conditional jump or move depends on uninitialised value(s)
==21536==    at 0x400A5E6: (within /lib/ld-2.11.1.so)
==21536==    by 0x40030FE: (within /lib/ld-2.11.1.so)
==21536==    by 0x4014206: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000C6C: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000856: (within /lib/ld-2.11.1.so)
==21536==
==21536== Conditional jump or move depends on uninitialised value(s)
==21536==    at 0x400AF0F: (within /lib/ld-2.11.1.so)
==21536==    by 0x40030FE: (within /lib/ld-2.11.1.so)
==21536==    by 0x4014206: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000C6C: (within /lib/ld-2.11.1.so)
==21536==    by 0x4000856: (within /lib/ld-2.11.1.so)
==21536==
==21536== Invalid read of size 8
==21536==    at 0x40B4785: (within /lib/tls/i686/cmov/libc-2.11.1.so)
==21536==    by 0x8049EFB: main (vcutil.c:496)
==21536==  Address 0x419d1b0 is 8 bytes before a block of size 120 alloc'd
==21536==    at 0x4025D2E: malloc (vg_replace_malloc.c:207)
==21536==    by 0x409DF9D: getdelim (in /lib/tls/i686/cmov/libc-2.11.1.so)
==21536==    by 0x408F3A2: getline (in /lib/tls/i686/cmov/libc-2.11.1.so)
==21536==    by 0x804947C: getUnfolded (vcutil.c:299)
==21536==    by 0x8049EFB: main (vcutil.c:496)
==21536==
==21536== Conditional jump or move depends on uninitialised value(s)
==21536==    at 0x40B47AD: (within /lib/tls/i686/cmov/libc-2.11.1.so)
==21536==    by 0x8049EFB: main (vcutil.c:496)
==21536==
==21536== Conditional jump or move depends on uninitialised value(s)
==21536==    at 0x8049524: getUnfolded (vcutil.c:307)
==21536==    by 0x8049EFB: main (vcutil.c:496)

我特别不知道这些行指的是什么

--21536-- Warning: DWARF2 CFI reader: unhandled DW_OP_ opcode 0x55

意思。这些是我更换发行版后的新功能。

无论如何,作为参考,这是我的问题:

VcStatus getUnfolded (FILE *const vcf, char **const buff) {

    //int const buffSize = 30;
    size_t lineSize = 0;
    int done = 0;  //Set to one if the next line checked does not entail unfolding
    static char* queue = NULL;  //A queue to store the next line read in
    static int lineNum = 0;  
    char* buffer = NULL;  //The dynamic memory that will be linked to buf
    int valid_line = 0;  //Set to one if the line contains characters other then whitespace
    char* temp; //Used to point to the location of \r\n in the buffer

    VcStatus error;  //Initialize VcStatus with appropriate values
    error.code = OK;
    error.linefrom = lineNum;
    error.lineto = 0;

    //Special case for resetting getUnfolded()
    if (vcf == NULL){      
        lineNum = 0;
        if (queue != NULL) queue = NULL;
        error.linefrom = 0;
        error.lineto = 0;
        return error;
    }

    //Copies any string contained in queue from last time into buffer
    if (queue != NULL) {
        buffer = malloc (strlen (queue)+1);
        strcpy (buffer, queue);
        strcpy (queue, "");
    }

    //If the end of file has been reached, last line is returned.
    if (feof (vcf) != 0) {
        queue = NULL;
        lineNum += 1;
        if (buffer != NULL) {
          if (strcmp (buffer, "") != 0)*buff = buffer;
        }
        else *buff = NULL;
        return error;
    }

    while (done == 0) {

        //Gets a new line from the vcf file, and returns null if there is no more data to be returned
        getline (&queue, &lineSize, vcf);

        if (ferror(vcf) != 0) {
          error.code = IOERR;
          return error;
        }

        //Sets valid_line to 1 if the line read in contains any characters other then whitespace
        for (int i = 0; i < strlen (queue); i++){
            if (queue[i] != '\r' && queue[i] != '\n' && queue[i] != ' ' && queue[i] != '\t') valid_line = 1;
        }

        if (feof (vcf) && valid_line == 0) {
            queue = NULL;
            break;
        }        

        if (valid_line == 1){
            //Finds the 'internet standard' newline and replaces it with a null terminator
            temp = strstr (queue, "\r\n");
            if (temp != NULL) strcpy (temp, "\0");

            //Sets the buffer equal to contents of queue and resets queue if buffer is empty
            if (buffer == NULL) {

                buffer = malloc (strlen (queue)+1);
                lineNum = lineNum + 1;          
                strcpy (buffer, queue);
                strcpy (queue, "");

            //Checks for leading whitespace to indicate a folded line, and unfolds
            }else if (queue [0] == ' ' || queue [0] == '\t') {

                lineNum = lineNum + 1;
                buffer = realloc (buffer, strlen (buffer)+strlen (queue)+2);
                strcat (buffer, queue+1);
                strcpy (queue, "");

            //If both conditions above are false, buffer contains the next valid line
            }else{

                error.lineto = lineNum;
                lineNum += 1;
                done = 1;

            }
        }
    }

    *buff = buffer;

    return error;

}

...以及向其发送测试数据的虚拟函数:

int main () {

    FILE* fp = fopen ("test.vcf", "r");

    char * buff;

    getUnfolded (fp, &buff);

}

test.vcf 文件实际上只是一个简单的文本文件

任何帮助都会很棒。

【问题讨论】:

  • 关于谷歌的事情很有趣:P 向你表明,如果这是第一个结果,我没有运气谷歌搜索这个问题。是的,我在这台新主机上重新编译了多次,源代码没有改变……test.vcf 文件使用了正确的 EOL CRLF……这是一个相当令人头疼的问题!
  • 如果我没记错的话,'dwarf2 opcode' 错误可能只是您使用的 valgrind 版本比您使用的编译器旧,可以放心地忽略。关于您的错误:您致电strlen(queue)。如果该行比lineSize 长,会发生什么?如果你得出代码没问题的结论,你可以生成一个抑制文件继续你的生活。
  • 感谢您的回复,很高兴理解为什么 valgrind 会向我吐出毫无意义的废话!如果您知道如何抑制这些错误,我将有兴趣学习如何抑制这些错误?而且我不知道如何解决您所指的错误。据我了解,如果队列从上次调用函数时开始包含某些内容,则调用该 strlen(queue) 行。我不断收到诸如“比较中使用未初始化的变量”之类的错误,因为我的变量已在条件语句中初始化(在每种情况下),我也不知道如何摆脱这些。
  • 哦,那个 lineSize 变量是没有意义的;我将把 0 硬编码到 getline 中。 Getline 无论如何都会“自动”调整缓冲区的大小,所以我什至看不到“建议的缓冲区大小”的意义:S
  • @Borealid - 你先生是我的英雄。我下载了最新版本的 valgrind 并对其进行了编译,现在我的错误为零。谢谢,女士们,先生们,案件已结案。胖女人唱了:D

标签: c linux valgrind


【解决方案1】:

您使用的 valgrind 版本已过时,因此它不会抑制正确的输出。这些错误在 suse 上仍然存在,它们只是被抑制了,因为它们在系统代码中。

需要手动安装最新版本的valgrind

这是我使用的论坛帖子

http://ubuntuforums.org/showthread.php?t=1608001

【讨论】:

    猜你喜欢
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 2019-06-13
    • 2014-04-09
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    相关资源
    最近更新 更多