Valgrind中的分割故障,但实际运行中没有

Segmentation fault in valgrind, but not in actual run

本文关键字:运行 分割 故障 Valgrind      更新时间:2023-10-16

我的代码在Valgrind内部运行时会产生分割故障,但是当运行正常运行时,它不会。怎么可能?

罪魁祸首,如Valgrind:

指出的那样
static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i )
{
    assert( i >= 0 && i < p->nSize );
    return p->pArray[i];
}

和Valgrind的消息:

Process terminating with default action of signal 11 (SIGSEGV)
==3290==  Access not within mapped region at address 0x0

如果代码通常运行完美,为什么会发生这种情况?我该如何解决?我需要对代码进行一些记忆分析。

如注释中所述,未定义的行为不必涉及崩溃。它可以很好地发挥作用。但是,这里似乎并非如此。

我们可以从消息中看到

Process terminating with default action of signal 11 (SIGSEGV)
==3290==  Access not within mapped region at address 0x0

该程序已尝试访问地址0x0。这通常意味着我们已经删除了一个无数分量。

查看您的代码:

static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i )
{
    assert( i >= 0 && i < p->nSize );
    return p->pArray[i];
}

通过断言i>=0i<p->nSize,我们可以看到您试图防止无效参数。但是,没有检查p本身有效。

您可以assert(p)以确保其不为空。您应该在现有断言之前执行此操作。

关于为什么仅在Valgrind下运行时才发生这种情况,一个重要的考虑是,程序在Valgrind下运行速度要慢得多,因此您可能已经暴露了一个仅在重负载下发生的问题,或者至少与与该行为完全不同的动态行为规范。

您如何解决此问题并通过内存分析前进?您需要修复错误。

  1. 使用调试器。GDB与Valgrind
  2. 很好地集成
  3. 使用断言来验证p是非null。

其中任何一个都应该让您看到后跟踪,并弄清楚为什么p为null。