perror()给seg。故障

时间:2012-09-24 21:35:36

标签: c linux gcc posix errno

发生错误后,我自然会拨打perror()。但是当我这样做时,我遇到了分段错误或printf("error: %s\n", strerror(errno));我不知道是什么在讨价还价。

  int fd;
  if((fd = open(FILENAME, O_RDONLY)) == -1) {
    perror("fbi");
    exit(1);
  }

  for(;;) {

    readed = read(fd, buffer, BUFSIZE);

    if(readed == 0)
      break;

    if(readed == -1) {
      perror("fbi"); // <- here's the error
      exit(1);
    }

如何解决这个问题?

更新

printf("%d\n", errno); // given 9

UPDATE2:

看起来与recv()函数中传递的缓冲区大小存在关系。如果BUFSIZE1,请提供上述错误。但如果BUFSIZE128,则{{1}} 无错误。有人可以解释这种行为吗?

2 个答案:

答案 0 :(得分:2)

无法确切地知道此代码段的错误。但总的来说,回答“为什么我在调用[rock solid c library func here]时会出现段错误?”通常是:你的筹码是炒的。阅读,当然是一个主要的嫌疑人。

答案 1 :(得分:1)

确定要使用#include <string.h>等。


我在宏中使用#include <errno.h>[...]printf("%s\n",strerror(errno));[...]几天都没有问题。然后,有一天,我向strerror(errno)添加了另一个调用,结果包括异常行为,分段错误,错误的返回类型,意外的程序终止(退出状态为0),所有这些都取决于我如何调用第二个strerror打电话。

strerror(errno)==NULL这样简单的事情将导致warning: comparison between pointer and integer

原来是因为我使用了strerror而没有#include <string.h>的原因。由于函数 是作为标准c库的一部分正确链接的,因此编译器会为函数创建一个(标准规定的)“隐式声明”,该隐式声明采用int strerror(int)的定义。不兼容的返回类型会引起问题,因为在我的系统上char*是64位,而int是32位。因此,取决于编译器如何安排内存空间,有时指针可以容纳32位,有时则不可以,有时不正确的地址恰好与其他分配的内存页匹配(未定义/空白输出),有时不匹配(分段故障)。我碰巧遇到了这样一种情况,它不能容纳32位,并且编译器将返回值“强制转换”为32位int,然后将其返回(对于printf)为64 char*位(没有丢失的64位的上半部分现在为零),并且在处理器尝试从未分配的内存页读取时出现未定义的行为。

诊断您的特殊情况将需要一个short, self contained, compilable, example (SSCCE),例如,您引用了一个recv函数调用(我假设您是读过吗?)。

您还需要包括用于编译代码的命令,例如,链接命令的顺序可能会显着改变生成的代码的行为。