【问题标题】:How do I trace a potential undefined behavior situation?如何跟踪潜在的未定义行为情况?
【发布时间】:2012-07-06 14:18:41
【问题描述】:

当指针关联时,我在解除分配时收到双重释放错误。我怀疑一些未定义的行为正在进行中,但我不知道从哪里开始寻找它,或者如何寻找它。您如何追踪未定义的行为?

编译器是intel 12。我无法发布代码,因为它很大,我什至不确定问题的根源在于我的代码。它可能在同事的图书馆里。我试图用 gdb 做一些调试,但我没有走得太远。这是错误。

malloc: * 对象 0x102302f20 的错误:未分配被释放的指针 * 在 malloc_error_break 中设置断点进行调试

紧接其前的那一行是 print *, associated(pointer),它打印 true。

这是回溯

#0  0x00007fff9327b6c0 in malloc_error_break ()
#1  0x00007fff9327b805 in free ()
#2  0x0000000100d27470 in for_dealloc_allocatable ()
#3  0x0000000100506699 in sharedarraysmodule_mp_deleterealsharedarray2_ () at SharedArrays.f90:609
#4  0x00000001003bbc4e in gammaaggregatormodule_mp_deleteprivate_ () at GammaAggregator.f90:86
#5  0x0000000102300bc0 in ?? ()
Previous frame inner to this frame (gdb could not unwind past this frame)

【问题讨论】:

  • 有困难!和一个调试器(也许)。向我们展示任何代码和错误消息,您使用的是什么编译器,通常的东西?
  • 是的,我正在这样做。我发了两次,所以我在队列中得到了双重打击
  • 你试过valgrind ./a.out吗?
  • @Zhenya:我不指望它会产生任何有意义的东西,除了由于代码编写方式可怕而导致的巨大回溯。任何信号都会被淹没。我已经去过那里

标签: fortran


【解决方案1】:

长评论,可能会指向(抱歉,无法抗拒)答案...

为了迂腐,看起来您的编译器的最佳猜测是“未分配指针被释放”。但在 Fortran 中,指针只有状态 undefinedassociateddisassociated,因此错误消息可能来自对编译器链接到可执行文件的系统函数的调用。

话虽如此,我会寻找:

  • 目标超出范围,而指向它的指针仍在范围内。 Fortran 2003 标准状态(注释 16.13)

    来自模块程序单元的指针可以通过使用关联在子程序中访问。 此类指针的生命周期大于子程序中声明的目标, 除非这样的目标被保存。因此,如果这样的指针与本地目标相关联,则存在 当子程序定义的过程完成执行时,目标的可能性 将不复存在,使指针“悬空”。本标准认为此类指针具有 未定义的关联状态。它们既没有关联也没有分离。他们不应 在程序中再次使用,直到重新建立其状态。没有要求 处理器能够检测指针目标何时不再存在。

同一文档还指出,传递给associated 内在函数的指针的关联状态不得未定义,因此程序可能可以撒谎并告诉您associated(undefined_pointer)==.true.

  • 一个可分配的目标正在被解除分配,无论是超出范围还是由于deallocate() 调用。
  • 指针在声明时无效,例如real, pointer :: rptr => null()(这通常被认为是一件好事,您可能会希望确保您的代码符合)。
  • 指针在关联之前被无效,但根据标准,我不认为使空指针无效是错误的。
  • 指向指针的指针。

您报告的错误消息往往表明您有模块变量超出范围的情况,但是,正如您已经观察到的那样,很难确定。

如果这没有帮助,请联系英特尔技术支持,我发现他们非常有帮助,他们非常擅长发现代码中的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-27
    • 1970-01-01
    • 2016-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多