Valgrind:libnvidia-glcore.so.346.47条件跳跃或移动取决于未初始化的值



当针对链接到NVIDIA的libGL的动态库运行我的测试c++应用程序时,Valgrind报告了以下错误(见下文)。我很想压制他们,但我不确定这是我的问题还是libnvidia-glcore.so的问题。部分不可靠的原因是没有完全理解瓦尔格里德的输出。在对glXCreateContextAttribsARB的调用中,我已经研究了代码中可能未初始化的变量,但没有发现任何变量。如果它出现在我的问题的输出中,我在寻找什么类型的东西?我得到的两个错误是:

==10156== Conditional jump or move depends on uninitialised value(s)
==10156==    at 0x7E4CAF4: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7DEE0CD: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7DEEADC: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7F75DA1: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7F775D3: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7E279BE: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7E27D21: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7F760F5: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7F3E353: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7A8C9C0: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x4E535F2: opengl_core::render_system::init() (x11_render_system.cpp:92)
==10156==    by 0x4040D8: test_render_system::run() (test_x11_render_system.cpp:10)
==10156==  Uninitialised value was created by a heap allocation
==10156==    at 0x4C29BCF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==10156==    by 0x5116428: ??? (in /usr/lib64/nvidia/libGL.so.346.47)
==10156==    by 0x7EECF2E: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7E479C1: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7DC8C31: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x50BF331: ??? (in /usr/lib64/nvidia/libGL.so.346.47)
==10156==    by 0x50EB72A: ??? (in /usr/lib64/nvidia/libGL.so.346.47)
==10156==    by 0x50EEA87: ??? (in /usr/lib64/nvidia/libGL.so.346.47)
==10156==    by 0x50E47D2: glXCreateContextAttribsARB (in /usr/lib64/nvidia/libGL.so.346.47)
==10156==    by 0x4E52EF8: opengl_core::render_context::init(opengl_core::render_window&, opengl_core::fb_config&) (x11_render_context.cpp:120)
==10156==    by 0x4E534D0: opengl_core::render_system::init() (x11_render_system.cpp:65)
==10156==    by 0x4040D8: test_render_system::run() (test_x11_render_system.cpp:10)
==10156== 

==10156== Conditional jump or move depends on uninitialised value(s)
==10156==    at 0x7E4CAF4: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7DEE0CD: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7DF085F: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7F4B78B: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7F4CFBC: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7E279BE: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7E27D21: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7F4BFE0: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7F38ED5: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7B20F52: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7F3E2CB: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7A8C9C0: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==  Uninitialised value was created by a heap allocation
==10156==    at 0x4C29BCF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==10156==    by 0x5116428: ??? (in /usr/lib64/nvidia/libGL.so.346.47)
==10156==    by 0x7EECF2E: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7E479C1: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x7DC8C31: ??? (in /usr/lib64/nvidia/libnvidia-glcore.so.346.47)
==10156==    by 0x50BF331: ??? (in /usr/lib64/nvidia/libGL.so.346.47)
==10156==    by 0x50EB72A: ??? (in /usr/lib64/nvidia/libGL.so.346.47)
==10156==    by 0x50EEA87: ??? (in /usr/lib64/nvidia/libGL.so.346.47)
==10156==    by 0x50E47D2: glXCreateContextAttribsARB (in /usr/lib64/nvidia/libGL.so.346.47)
==10156==    by 0x4E52EF8: opengl_core::render_context::init(opengl_core::render_window&, opengl_core::fb_config&) (x11_render_context.cpp:120)
==10156==    by 0x4E534D0: opengl_core::render_system::init() (x11_render_system.cpp:65)
==10156==    by 0x4040D8: test_render_system::run() (test_x11_render_system.cpp:10)
==10156== 

根据要求:

 // src/x11_render_system.cpp
 91       m_impl->m_context.make_current(m_impl->m_window);
 92       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 93       glClearColor(1.0, 0.0, 0.0, 1.0);  
 94       glXSwapBuffers(display, window);   
 95       m_impl->m_context.make_not_current();

Valgrind在使用关键硬件驱动程序(如GPU驱动程序)时,由于其工作方式,很容易出现误报。基本上,这些驱动程序通过BIOS设置的用户空间(虚拟RAM)访问GPU的内存(甚至寄存器)(这是工作中的POSIX mmap)。通过这种方式,驱动程序可以通过任意地址访问设备的寄存器,就像任何其他变量一样。

关键是有些设备的寄存器只是用来读取的。例如,它们可以反映设备的某些状态。因此,只有设备有理由写入它们(即使CPU试图这样做,它也会失败)。大多数情况下,它在通电时在内部执行,在状态更改时不时执行,并且在设置映射时反映到用户空间。本质上,这些都是纯粹的波动性变量。。。甚至比它通常的线程对线程概念更易失,顺便说一句,Valgrind很好地处理了这一概念,因为它模拟CPU。

但Valgrind生活在一个决定论世界(CPU和RAM)中,这些GPU的寄存器完全不在这个世界中。当驱动程序读取它们时,Valgrind只是认为它在访问RAM(由于mmap),这绝对不是真的。因此,在驱动程序使用读取的数据(某些设备状态)进行相应分支时,Valgrind报告称,因为其世界上没有任何人写过这些数据。

老实说:专有驱动程序不是开源的,所以很难猜测到底发生了什么,但很可能是类似的事情。我可以肯定的是,Valgrind和GPU驱动程序早就发生了这种情况(即使是非常小的程序),主要是在初始化期间,每个人都认为这些都是误报。因此,您可以安全地忽略它…或者在您的项目中为Valgrind创建一个抑制文件(让我们将其命名为Valgrind.supp):

{
  NVidia-driver
  Memcheck:Cond
  obj:/usr/lib64/nvidia/libnvidia-glcore.so.346.47
}

然后你用选项--suppressions=Valgrind.supp调用Valgrind,它将不再报告这些假阳性。

您可能有其他与此相关的驱动程序对象,只需为它们添加条目(您必须重复整个{…}并修改对象线以匹配Valgrind报告)。由于版本发生了变化,每次更新驱动程序时,您可能也必须更新它们,不过我想您可以使用基本的通配符来避免这种情况。

在这里查看更多关于Valgrind功能的信息。

获取以下代码:

bool x_init = false;
int x;
void initX(){
    x = 4;
    x_init = true;
}
bool X_initialized(){
    x_init;
}
//...
if( X_initialized() && x <3){
    doSomething(x);
}

在这种情况下,很明显,x不是在未初始化的情况下使用的,但是编译器/valgrind必须证明这一点,并且它看到的是"x<3"在使用x时没有初始化它。证明关于代码的任意内容通常是不可能的。因此,如果驱动程序被混淆,或者只是在没有使用valgrind的情况下进行编码(驱动程序供应商往往有数百万的测试,所以他们很可能更依赖于他们的测试而不是分析工具),那么valgrind很可能检测不到这一点(这不是valgrind失败,而是数学限制,如果你希望第三方代码的编码风格失败的话)。

然而,您应该向您正在使用的代码(NVIDIA?)的维护人员报告,这可能是一个需要解决的问题。

另一种可能性是,在某个时候,他们的代码需要"随机行为",因此他们使用未初始化的值作为非确定性数据的源(没有银弹,如果你使用覆盖率工具,你很快就会知道这并不总是可能的。有100%的覆盖率,如果你用分析工具,它们迟早也会失败)。。

另一种可能性是,这些"未初始化"的值只是"易失性"变量,在加载驱动程序时(在系统助推之后)进行初始化,因此"应用程序"无法将其视为已初始化(可能是最合理的情况)

您可以显示x11_render_system.cpp:92 周围的代码

但在我看来,valgrind也可能会出错,如果你没有发现valgrind 出错的任何问题,就忽略它。

相关内容

最新更新