为什么在添加printf行后没有触发SIGFPE?

时间:2016-06-18 17:38:43

标签: c linux signals

我正在玩一个简单的程序(下面的源代码)。我的电脑配置:

Linux mymachine 3.13.0-49-generic#83-Ubuntu SMP Fri Apr 10 20:11:33 UTC 2015 x86_64 x86_64 x86_64 GNU / Linux

gcc版本4.8.4(Ubuntu 4.8.4-2ubuntu1~14.04.3)

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

void catcher(int a){
  setresuid(geteuid(),geteuid(),geteuid());
  printf("WIN!\n");
  system("/bin/sh");
  exit(0);
}

int main(int argc, char **argv){
  puts("source code is available in level02.c\n");

  if (argc != 3 || !atoi(argv[2]))
    //printf("!atoi(argv[2]) = %d\n", !atoi(argv[2]));
    return 1;
  signal(SIGFPE, catcher);
  printf("end\n");

  return abs(atoi(argv[1])) / atoi(argv[2]);
}

我打算通过以这种方式调用可执行文件来触发此程序中的SIGFPE:

$./a.out -2147483648 -1
source code is available in level02.c

end
WIN!

如您所见,SIGFPE已成功触发。但是,如果我在参数中取消注释单个printf行,检查“if”条件:

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

void catcher(int a){
  setresuid(geteuid(),geteuid(),geteuid());
  printf("WIN!\n");
  system("/bin/sh");
  exit(0);
}

int main(int argc, char **argv){
  puts("source code is available in level02.c\n");

  if (argc != 3 || !atoi(argv[2]))
    printf("!atoi(argv[2]) = %d\n", !atoi(argv[2]));
    return 1;
  signal(SIGFPE, catcher);
  printf("end\n");

  return abs(atoi(argv[1])) / atoi(argv[2]);
}

然后我重新编译程序并尝试使用相同的方式触发SIGFPE。我只能得到这个:

source code is available in level02.c

发生了什么事?

1 个答案:

答案 0 :(得分:1)

因为现在你的源代码与实际解析它的方式相比是错误的。

if (argc != 3 || !atoi(argv[2]))
    printf("!atoi(argv[2]) = %d\n", !atoi(argv[2]));
return 1;

考虑将两个语句放在一个块中,以避免这种情况。