【问题标题】:Stack Smashing Issue With Pipes, greps, wc in CC 中管道、greps、wc 的堆栈粉碎问题
【发布时间】:2018-09-27 03:49:13
【问题描述】:

编辑:** 已回答问题:参见 PaulMckenzie 和 Rishikesh Raje 的 cmets

此函数的目的是使用管道在参数file 上调用grep 参数pattern,但我的程序中存在堆栈粉碎问题。它运行并直接运行到函数的末尾,但随后抱怨堆栈粉碎。 这是我的代码:

void count_pattern(char *file, char *pattern) {
  int bytes_read;
  int nbytes = 20000;
  char *read_string;
  char grep_str[] = "";
  FILE *grep_pipe;
  FILE *wc_pipe;

  strcat(grep_str, "grep ");
  strcat(grep_str, pattern);
  strcat(grep_str, " ");
  strcat(grep_str, file);
  strcat(grep_str, "\0");

  grep_pipe = popen (grep_str, "r");
  wc_pipe = popen ("wc -l", "w");

  /* Pipe Error Checking*/
  if ((!grep_pipe) || (!wc_pipe))
  {
      fprintf (stderr,"One or both pipes failed.\n");
  }
  /* Read from grep_pipe until EOF? */
  read_string = (char *) malloc (nbytes + 1);
  bytes_read = getdelim (&read_string, &nbytes, -1, grep_pipe);


  /* Close grep_pipe */
  if (pclose (grep_pipe) != 0)
  {
      fprintf (stderr, "Could not run 'grep'.\n");
  }

  /* Send output of 'grep' to 'wc' */
  fprintf (wc_pipe, "%s", read_string);

  /* Close wc_pipe */
  if (pclose (wc_pipe) != 0)
  {
      fprintf (stderr, "Could not run 'wc'.\n");
  }

printf("%s\n\n",grep_str); /* migrating bug-check print statement */
}

使用参数 file="somefile" pattern="somepattern" 通过 main 运行它会在 somefile 中输出正确数量的 somepatterns 以及最后的典型迁移错误检查打印语句,之后它因堆栈粉碎而终止。

阅读堆栈粉碎后,似乎管道的某些末端过度扩展了对非法空间的读取或写入。但是,我不确定发生在哪里或为什么会发生这种情况,因为在函数结束之前一切似乎都运行良好。此处有关堆栈粉碎的其他帖子暗示,当堆栈粉碎可能发生时,是编译器将金丝雀扔到代码中表示失败。问题也不在于main。任何人都可以了解情况吗?

参考: http://crasseux.com/books/ctutorial/Programming-with-pipes.html

是这段代码主要基于的地方。

【问题讨论】:

  • strcat(grep_str, "grep "); -- strcat 要求目的地有空间容纳将要附加的字符。显然grep_str 没有这个房间。换句话说,你有一个缓冲区溢出。
  • char grep_str[] = "" 该语句将只为grep_str 分配2 个字节。您应该根据您的模式分配适当大小的数组。例如char grep_str[100] = ""
  • 您知道,有时您认为自己感觉不到任何愚蠢,然后就会发生这种情况。感谢@PaulMcKenzie 和 Rishikesh Raje(只能@1)!就是这样
  • @SamOwens:您可以添加此问题的答案,以便将其从未回答的列表中删除。

标签: c pipe system-calls popen stack-smash


【解决方案1】:

问题不在于管道。该问题与字符串与空字符串变量 grep_str 的连接有关,该变量显然无法在其中容纳更多字符串。感谢 cmets 中的 Paul 和 Rishikesh

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多