首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于在没有发现漏洞时调试分段错误的提示

关于在没有发现漏洞时调试分段错误的提示
EN

Stack Overflow用户
提问于 2011-12-19 22:19:50
回答 3查看 2.2K关注 0票数 5

我编写了一个基于C的应用程序,它看起来运行得很好,除了在非常大的数据集上作为输入。

如果输入量很大,则在二进制功能的最后一步就会出现分段错误。

我使用valgrind运行二进制文件(带有测试输入)

代码语言:javascript
复制
valgrind --tool=memcheck --leak-check=yes /foo/bar/baz inputDataset > outputAnalysis

这份工作通常需要几个小时,但对于valgrind,它需要七天时间。

不幸的是,在这一点上,我不知道如何读取我从这次运行中得到的结果。

我收到很多这样的警告:

代码语言:javascript
复制
...
==4074== Conditional jump or move depends on uninitialised value(s)                                                                                                                  
==4074==    at 0x435900: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x439CC5: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x400BF2: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x402086: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x402A0F: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x41684F: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x4001B8: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x7FEFFFF57: ???                                                                                                                                                      
==4074==  Uninitialised value was created                                                                                                                                            
==4074==    at 0x461D3A: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x43F926: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x416B9B: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x416725: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x4001B8: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x7FEFFFF57: ???
...

没有暗示代码的部分,没有变量的名称等等。我能对这些信息做些什么呢?

最后,我最终得到了以下错误,但是--与没有崩溃的小型数据集一样-- valgrind没有发现泄漏:

代码语言:javascript
复制
...
==4074== Process terminating with default action of signal 11 (SIGSEGV)                                                                                                              
==4074==  Access not within mapped region at address 0x7158E7F7                                                                                                                      
==4074==    at 0x7158E7F7: ???                                                                                                                                                       
==4074==    by 0x4020B8: ??? (in /foo/bar/baz)                                                                                   
==4074==    by 0x6322203A22656D6E: ???                                                                                                                                               
==4074==    by 0x306C675F6E557267: ???                                                                                                                                               
==4074==    by 0x202C22373232302F: ???                                                                                                                                               
==4074==    by 0x6D616E656C696621: ???                                                                                                                                               
==4074==    by 0x72686322203A2264: ???                                                                                                                                               
==4074==    by 0x3030306C675F6E54: ???                                                                                                                                               
==4074==    by 0x346469702E373231: ???                                                                                                                                               
==4074==    by 0x646469662E34372F: ???                                                                                                                                               
==4074==    by 0x722E64616568656B: ???                                                                                                                                               
==4074==    by 0x63656D6F6C756764: ???                                                                                                                                               
==4074==  If you believe this happened as a result of a stack                                                                                                                        
==4074==  overflow in your program's main thread (unlikely but                                                                                                                       
==4074==  possible), you can try to increase the size of the                                                                                                                         
==4074==  main thread stack using the --main-stacksize= flag.                                                                                                                        
==4074==  The main thread stack size used in this run was 10485760.                                                                                                                  
==4074==                                                                                                                                                                             
==4074== HEAP SUMMARY:                                                                                                                                                               
==4074==     in use at exit: 0 bytes in 0 blocks                                                                                                                                     
==4074==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated                                                                                                                    
==4074==                                                                                                                                                                             
==4074== All heap blocks were freed -- no leaks are possible                                                                                                                         
==4074==                                                                                                                                                                             
==4074== For counts of detected and suppressed errors, rerun with: -v                                                                                                                
==4074== ERROR SUMMARY: 1603141870 errors from 86 contexts (suppressed: 0 from 0)
Segmentation fault

分配空间的所有内容都会得到一个等价的free语句,然后设置指向NULL的指针。

此时,我如何最好地调试这个应用程序,以确定是什么导致了分段错误?

2011年12月22日-编辑

我使用以下编译标志编译了名为debug-binary的二进制文件的调试版本:

代码语言:javascript
复制
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE=1 -DUSE_ZLIB -g -O0 -Wformat -Wall -pedantic -std=gnu99

当我使用valgrind运行它时,我没有得到更多的信息:

代码语言:javascript
复制
valgrind -v --tool=memcheck --leak-check=yes --error-limit=no --track-origins=yes debug-binary input > output

下面是输出片段:

代码语言:javascript
复制
==25116== 2 errors in context 14 of 14:                                                                                                                                                                                                      
==25116== Invalid read of size 4                                                                                                                                                                                                             
==25116==    at 0x4045E8: ??? (in /foo/bar/debug-binary)                                                                                                                                 
==25116==    by 0x40682F: ??? (in /foo/bar/debug-binary)                                                                                                                                 
==25116==    by 0x404F0C: ??? (in /foo/bar/debug-binary)                                                                                                                                 
==25116==    by 0x401FA4: ??? (in /foo/bar/debug-binary)                                                                                                                                 
==25116==    by 0x402016: ??? (in /foo/bar/debug-binary)                                                                                                                                 
==25116==    by 0x403B27: ??? (in /foo/bar/debug-binary)                                                                                                                                 
==25116==    by 0x40295E: ??? (in /foo/bar/debug-binary)                                                                                                                                 
==25116==    by 0x31A021D993: (below main) (in /lib64/libc-2.5.so)                                                                                                                                                                           
==25116==  Address 0x539f188 is 24 bytes inside a block of size 48 free'd                                                                                                                                                                    
==25116==    at 0x4A05D21: free (vg_replace_malloc.c:325)                                                                                                                                                                                    
==25116==    by 0x401F6B: ??? (in /foo/bar/debug-binary)                                                                                                                                 
==25116==    by 0x402016: ??? (in /foo/bar/debug-binary)                                                                                                                                 
==25116==    by 0x403B27: ??? (in /foo/bar/debug-binary)                                                                                                                                 
==25116==    by 0x40295E: ??? (in /foo/bar/debug-binary)                                                                                                                                 
==25116==    by 0x31A021D993: (below main) (in /lib64/libc-2.5.so) 

这是我的二进制文件的问题,还是我的应用程序所依赖的系统库(libc)的问题?

我也不知道如何解释???条目。是否还需要另一个编译标志来获得valgrind以提供更多信息?

EN

回答 3

Stack Overflow用户

发布于 2011-12-19 22:30:56

基本上,瓦伦丁说没有显著的堆管理问题。该程序正在从一个不太复杂的编程故障中分割故障。

如果是我,我会

  • gcc -g编译它,
  • 启用核心转储文件(ulimit -c unlimited),
  • 正常运行该程序,
  • 并让它出错H 210H 111使用gdb检查核心文件并查看其出错时所做的事情:

gdb (程序文件)(核心文件)

bt

票数 6
EN

Stack Overflow用户

发布于 2011-12-19 22:45:01

我不相信valgrind能够在堆栈上找到超出值的所有错误(但不会超出堆栈本身)。所以,你可能想试试gcc的-f-stack-protector-all选项。

您还应该尝试使用-fmudflap (单线程)或-fmudflapth (多线程)。

挡泥板和堆叠保护器都应该比瓦磨快得多。

此外,看起来您没有调试符号,因此很难读取回溯。添加-ggdb。您可能还希望启用核心文件生成(尝试ulimit -c unlimited)。这样,您可以尝试使用gdb program core调试崩溃后的进程。

正如@wallyk所指出的那样,您的分段错误实际上可能很容易找到--例如,您可能正在取消引用NULL,gdb可以指向确切的行(或者,除非您使用-O0进行编译,否则关闭)。例如,如果您只是为较大的数据集运行内存,而malloc返回NULL,那么这将是有意义的,而您忘了在某个地方检查它。

最后,如果没有其他有意义的东西,总有可能出现硬件问题。但是这些都是随机的,例如,不同的值被破坏了不同的运行。如果你尝试另一台机器,它发生在那里,它不太可能是一个硬件问题。

票数 4
EN

Stack Overflow用户

发布于 2011-12-19 23:24:49

“条件跳转或移动依赖于未初始化的值”是您需要修复的严重错误。它表示程序的行为受到未初始化变量(包括malloc()返回的未初始化内存区域)内容的影响。

要从valgrind获得可读的回溯,您需要使用-g进行编译。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8568335

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档