使用memchr计数输入行失败

时间:2018-09-25 22:34:11

标签: c gcc segmentation-fault

我编写了一个程序来计算stdin给定的输入行数:

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#define BUFF_SIZE  8192
#define RS  '\n'

int
main(int argc, char **argv)
{
    char buff[BUFF_SIZE];
    ssize_t n;
    char *r; 
    int c = 0;

    readchunk:
    n = read(0, buff, BUFF_SIZE);
    if (n<=0) goto end; // EOF
    r=buff;

    searchrs:
    r = memchr(r, RS, n);
    if(r!=NULL) {
        c++;
        if((r-buff)<n) {
            ++r;
            goto searchrs;
        }
    }
    goto readchunk;

    end:
    printf("%d\n", ++c);
    return 0;
}

我用gcc编译了它,没有任何选择。

运行时,它会产生不稳定的结果,与真相相距不远,但错误。有时会出现段错误。缓冲区大小越大,段故障就越频繁。

我在做什么错了?

1 个答案:

答案 0 :(得分:0)

使用-fsanitize=address构建程序并将其输入足够长的输入会产生:

==119818==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffedbba1500 at pc 0x7fc4d56fd574 bp 0x7ffedbb9f4a0 sp 0x7ffedbb9ec50
READ of size 8192 at 0x7ffedbba1500 thread T0
    #0 0x7fc4d56fd573  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x40573)
    #1 0x563fdf5f4b90 in main /tmp/t.c:23
    #2 0x7fc4d533e2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #3 0x563fdf5f49c9 in _start (/tmp/a.out+0x9c9)

Address 0x7ffedbba1500 is located in stack of thread T0 at offset 8224 in frame
    #0 0x563fdf5f4ab9 in main /tmp/t.c:11

  This frame has 1 object(s):
    [32, 8224) 'buff' <== Memory access at offset 8224 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x40573)

第23行是对memchr的呼叫。

递增r时,可能应该递减n