【问题标题】:Unexpected stack smashing意外的堆栈粉碎
【发布时间】:2014-02-09 23:52:51
【问题描述】:

我用 c 编写了一个压缩器(程序),它可以完美地处理文件,除了一个不断给我堆栈粉碎错误而我无法确定原因的文件。

GDB 错误

Breakpoint 1, load (wordlist=0x7fffffffd760, file=0x7fffffffe444 "Doxyfile", size=0x7fffffffdf94, uniqueWord=0x7fffffffdf98) at hashstruct.c:286
286   fclose(fp);
(gdb) n
288   return 0;
(gdb) n
289 }
(gdb) n
*** stack smashing detected ***: /home/sujit/c/cproject/util terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x37)[0x7ffff7828f47]
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x0)[0x7ffff7828f10]
/home/sujit/c/cproject/util[0x403486]
/home/sujit/c/cproject/util[0x40218f]
/home/sujit/c/cproject/util[0x400f60]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7ffff773f76d]
/home/sujit/c/cproject/util[0x400a69]
======= Memory map: ========
00400000-00405000 r-xp 00000000 08:06 1574093                            /home/sujit  /c/cproject/util
00604000-00605000 r--p 00004000 08:06 1574093                            /home/sujit/c/cproject/util
00605000-00606000 rw-p 00005000 08:06 1574093                            /home/sujit/c/cproject/util
00606000-01014000 rw-p 00000000 00:00 0                                  [heap]
7ffff7508000-7ffff751d000 r-xp 00000000 08:06 134958                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff751d000-7ffff771c000 ---p 00015000 08:06 134958                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff771c000-7ffff771d000 r--p 00014000 08:06 134958                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff771d000-7ffff771e000 rw-p 00015000 08:06 134958                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff771e000-7ffff78d3000 r-xp 00000000 08:06 131977                     /lib/x86_64-linux-gnu/libc-2.15.so
7ffff78d3000-7ffff7ad3000 ---p 001b5000 08:06 131977                     /lib/x86_64-linux-gnu/libc-2.15.so
7ffff7ad3000-7ffff7ad7000 r--p 001b5000 08:06 131977                     /lib/x86_64-linux-gnu/libc-2.15.so
7ffff7ad7000-7ffff7ad9000 rw-p 001b9000 08:06 131977                     /lib/x86_64-linux-gnu/libc-2.15.so
7ffff7ad9000-7ffff7ade000 rw-p 00000000 00:00 0 
7ffff7ade000-7ffff7bd9000 r-xp 00000000 08:06 141974                     /lib/x86_64-linux-gnu/libm-2.15.so
7ffff7bd9000-7ffff7dd8000 ---p 000fb000 08:06 141974                     /lib/x86_64-linux-gnu/libm-2.15.so
7ffff7dd8000-7ffff7dd9000 r--p 000fa000 08:06 141974                     /lib/x86_64-linux-gnu/libm-2.15.so
7ffff7dd9000-7ffff7dda000 rw-p 000fb000 08:06 141974                     /lib/x86_64-linux-gnu/libm-2.15.so
7ffff7dda000-7ffff7dfc000 r-xp 00000000 08:06 141975                     /lib/x86_64-linux-gnu/ld-2.15.so
7ffff7fda000-7ffff7fdd000 rw-p 00000000 00:00 0 
7ffff7ff7000-7ffff7ffb000 rw-p 00000000 00:00 0 
7ffff7ffb000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00022000 08:06 141975                     /lib/x86_64- linux-gnu/ld-2.15.so
7ffff7ffd000-7ffff7fff000 rw-p 00023000 08:06 141975                     /lib/x86_64-linux-g gnu/ld-2.15.so
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Program received signal SIGABRT, Aborted.
0x00007ffff7754425 in __GI_raise (sig=<optimized out>)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
64  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.

加载函数的代码是:

int
load (hashstruct * wordlist, char *file, int *size, int *uniqueWord)
{
  // initialising wordlist
  hashstruct_deafult_value (wordlist, NULL, (char) 0);
  // declaring word
  char word[LENGTH];
  // opening the file
  FILE *fp = fopen (file, "r");
  // proceding if the file is succesfully opened
  if (fp != NULL)
    {
      while (getWord (fp, word) != EOF) //fscanf(fp,"%s",word) != EOF)
        {
          hashstruct *back;
          int returnValue = hash_put (wordlist, word, uniqueWord, &back);
          if (returnValue != 0)
            return returnValue;
          sizeadd (size);
        }
    }
  else
    {
      fprintf (stderr, "unable to open file");
      return -1;
    }
  fclose (fp);
  return 0;
}


int getWord(FILE* inptr, char word[])
{
 int noofchar = 0;
 int c = 0;
 if ( feof(inptr) )
 {
return EOF;
 }
else
 {

  while ( (c = getc(inptr)) != EOF && c != ' ' )
{
    if ( !(c > 0 && c < 256) )
        fprintf(stderr,"\nnot in char range"); 
    if (noofchar >= LENGTH)
    {
        fprintf(stderr,"\nbuffer memory overflow in getWord");
        break;
    }
            word[noofchar++] = (char)c;
}

  word[noofchar]='\0';
  return noofchar;
  }
  }

【问题讨论】:

  • (char)0); 你的意思是:(char*)0); 吗? (或者只是:NULL 哪个更简单?)
  • 问题不太可能出现在这个函数中——在某些时候,你已经覆盖了程序的“程序结束时要做什么”部分,现在你的程序已经结束了,错误被发现。
  • 它的 (char)0 即 NULL 字符
  • 如果getWordfscanf(fp,"%s",word) 执行相同的操作(正如该行的注释可能暗示的那样),请确保它不能将超过LENGTH 字符(包括空终止符)读入@987654329 @(即当使用 scanf-family 时,使用 %s 说明符的长度参数)
  • while ( getWord(fp,word) != EOF ) 这看起来很危险。 getWord() 是否知道缓冲区的大小是 LENGTH,或者它是否高兴地溢出大于 LENGTH 个字符的单词?

标签: c


【解决方案1】:

我不知道这是否是你的问题,但请看以下代码:

/* in load() */

char word[LENGTH];
FILE *fp = fopen (file, "r");

/* in getWord () */

  if (noofchar >= LENGTH)
  {
      fprintf(stderr,"\nbuffer memory overflow in getWord");
      break;
  }
  word[noofchar++] = (char)c;
}

word[noofchar]='\0';

如果您存储的正是LENGTH 字符,那么最后一行将写入终止0 超出word 缓冲区的末尾,并且可能 破坏fp,这很可能在fclose() 中崩溃你的程序。

【讨论】:

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