2012-12-02 50 views
2

我试图在使用Valgrind的代码中的免费错误后调试使用。使用Valgrind免费调试后使用

我的代码在试图访问先前删除的对象时崩溃了。在这种情况下使用Valgrind有没有办法查看谁删除了对象?

我跑Valgrind使用下面的选项,但它只捕捉崩溃,并显示它发生的地方。我希望能得到该对象被释放的细节:

的valgrind --tool = MEMCHECK

+0

'cout << ptr <<'\ n';'在每个free(ptr)之前;'分析输出。这就是所谓的调试。你为什么在C++中使用'free'? –

+0

@LightnessRacesinOrbit无关紧要。只是你将要释放的指针的地址不会帮助你。无效的'free()'是未定义的行为,你不能相信它会一直崩溃。 – Zaffy

+0

如果他在适当的地方写指针值和'__LINE__'以及其他的上下文,它根本就不是“无关紧要的”;这是基本的调试,并且已经有几十年了。 –

回答

3

这是我在这些情况下使用:

valgrind --track-origins=yes 

在释放后使用-的情况下,它会告诉你,free'd内存/删除对象的函数的堆栈跟踪。

有关注意事项,请阅读Valgrind的手册页,特别是关于性能的手册。如果您的问题是并发问题,则较慢的Valgrind可能会更改程序的计时属性,并可能更改(减少或增加)发生该错误的可能性。

--track-origins=<yes|no> [default: no] 
    Controls whether Memcheck tracks the origin of uninitialised 
    values. By default, it does not, which means that although it can 
    tell you that an uninitialised value is being used in a dangerous 
    way, it cannot tell you where the uninitialised value came from. 
    This often makes it difficult to track down the root problem. 

    When set to yes, Memcheck keeps track of the origins of all 
    uninitialised values. Then, when an uninitialised value error is 
    reported, Memcheck will try to show the origin of the value. An 
    origin can be one of the following four places: a heap block, a 
    stack allocation, a client request, or miscellaneous other sources 
    (eg, a call to brk). 

    For uninitialised values originating from a heap block, Memcheck 
    shows where the block was allocated. For uninitialised values 
    originating from a stack allocation, Memcheck can tell you which 
    function allocated the value, but no more than that -- typically it 
    shows you the source location of the opening brace of the function. 
    So you should carefully check that all of the function's local 
    variables are initialised properly. 

    Performance overhead: origin tracking is expensive. It halves 
    Memcheck's speed and increases memory use by a minimum of 100MB, 
    and possibly more. Nevertheless it can drastically reduce the 
    effort required to identify the root cause of uninitialised value 
    errors, and so is often a programmer productivity win, despite 
    running more slowly. 

    Accuracy: Memcheck tracks origins quite accurately. To avoid very 
    large space and time overheads, some approximations are made. It is 
    possible, although unlikely, that Memcheck will report an incorrect 
    origin, or not be able to identify any origin. 

    Note that the combination --track-origins=yes and 
    --undef-value-errors=no is nonsensical. Memcheck checks for and 
    rejects this combination at startup. 
+0

谢谢,这看起来正是我正在寻找的!它现在正在崩溃,Valgrind正在赶上它,但我有一些问题(我将在下一个评论中解释)。我确实遇到了Valgrind没有崩溃的问题,因为它运行较慢/是多线程的,但我通过删除执行过程中打印的很多语句来解决这个问题。 – xur17

+0

它现在崩溃的消息:'进程终止与信号11(SIGSEGV)的默认行动访问不在映射区域在地址0x0'我不确定这意味着什么,但是。 – xur17

+0

@ xur17这意味着Valgrind捕获了一个NULL指针解引用('不在地址0x0处的映射区域内访问),并使用其默认操作将其转发给进程,即终止程序。 –

1

Valgrind的表现出你最大的它可以。您需要使用更多的调试信息来编译代码 - 然后valgrind将能够向您显示更多信息,例如文件,函数和行。

-g选项编译您的代码并重新运行valgrind。在某些编译器上还有-gN,其中N是调试级别。但在大多数情况下,-g就足够了。

+0

我得到了它坠毁的位置的回溯,以及它坠毁的确切行号,但没有提到对象之前被删除的位置。我现在有-g选项。 – xur17

+0

@ xur17我确定valgrind做到了。阅读来自valgrind的所有报告。当你处理无效内存时,它的内存错误并不意味着有必要崩溃。寻找无效的读/写。 – Zaffy

+0

@ xur17或......当你知道问题出在哪里时,试着分析它是如何制作的,我想你会得到它。 – Zaffy