Valgrind:libnvidia-glcore.so.346.47 条件跳转或移动取决于未初始化的值
Valgrind: libnvidia-glcore.so.346.47 Conditional jump or move depends on uninitialised value
当 运行 我的测试 c++ 应用程序针对链接到 NVIDIA libGL.so 的动态库时,我收到 Valgrind 报告的以下错误(见下文)。我很想压制它们,但我不确定这是我的问题还是 libnvidia-glcore.so 的问题。部分不确定性源于没有完全理解 Valgrind 的输出。我已经查看了在调用 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();
您可以显示代码 x11_render_system.cpp:92
但我认为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 没有在未初始化的情况下使用,但是 compiler/valgrind 必须证明这一点,并且它看到的是 "x<3" 正在使用 x 而没有初始化它。证明任意关于代码的东西通常是不可能的。因此,如果驱动程序被混淆或只是在不使用 valgrind 的情况下进行编码(驱动程序供应商倾向于进行数百万次测试,因此他们很可能更依赖于他们的测试而不是分析工具)很可能 valgrind 无法检测到(这不是失败) valgrind,但有一个数学限制,如果您希望第三方代码的编码风格失败)。
但是您应该向您正在使用的代码(NVIDIA?)的维护者报告,这可能是一个需要修复的问题。
另一种可能性是,在某些时候他们的代码需要 "Random behaviour",因此他们使用未初始化的值作为非确定性数据的来源(没有灵丹妙药,如果您使用覆盖工具,您很快就会知道这并不总是可能有 100% 的覆盖率,如果您使用分析工具,它们迟早也会失败)..
另一个机会是那些 "uninitialized" 值只是 "volatile" 变量,它们在加载驱动程序时(在系统 boostrap 之后)被初始化,因此 "application" 无法将它们视为已初始化(可能是最合理的情况)
由于关键硬件驱动程序(例如 GPU 驱动程序)的工作方式,Valgrind 很容易出现误报。基本上,这些驱动程序通过 BIOS 设置的用户 space(虚拟 RAM)访问 GPU 的内存(甚至 寄存器 )(这是 POSIX mmap at工作)。这样,驱动程序可以通过任意地址访问设备的寄存器,就像任何其他变量一样。
重点是某些设备的寄存器仅供读取。例如,它们可以反映设备的某些状态。因此,只有设备有理由写入它们(即使 CPU 尝试这样做,它也会失败)。大多数情况下,它会在开机时在内部执行此操作,并且有时会在状态更改时执行此操作,并在设置映射时向用户 space 反映。本质上,这些是纯粹的易变变量......甚至比通常的线程到线程概念更易变,顺便说一下,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 报告的内容)。由于版本更改,您可能还必须在每次更新驱动程序时更新它们,但我想您可以使用基本通配符来避免这种情况。
查看 here 了解有关此 Valgrind 功能的更多信息。
当 运行 我的测试 c++ 应用程序针对链接到 NVIDIA libGL.so 的动态库时,我收到 Valgrind 报告的以下错误(见下文)。我很想压制它们,但我不确定这是我的问题还是 libnvidia-glcore.so 的问题。部分不确定性源于没有完全理解 Valgrind 的输出。我已经查看了在调用 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();
您可以显示代码 x11_render_system.cpp:92
但我认为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 没有在未初始化的情况下使用,但是 compiler/valgrind 必须证明这一点,并且它看到的是 "x<3" 正在使用 x 而没有初始化它。证明任意关于代码的东西通常是不可能的。因此,如果驱动程序被混淆或只是在不使用 valgrind 的情况下进行编码(驱动程序供应商倾向于进行数百万次测试,因此他们很可能更依赖于他们的测试而不是分析工具)很可能 valgrind 无法检测到(这不是失败) valgrind,但有一个数学限制,如果您希望第三方代码的编码风格失败)。
但是您应该向您正在使用的代码(NVIDIA?)的维护者报告,这可能是一个需要修复的问题。
另一种可能性是,在某些时候他们的代码需要 "Random behaviour",因此他们使用未初始化的值作为非确定性数据的来源(没有灵丹妙药,如果您使用覆盖工具,您很快就会知道这并不总是可能有 100% 的覆盖率,如果您使用分析工具,它们迟早也会失败)..
另一个机会是那些 "uninitialized" 值只是 "volatile" 变量,它们在加载驱动程序时(在系统 boostrap 之后)被初始化,因此 "application" 无法将它们视为已初始化(可能是最合理的情况)
由于关键硬件驱动程序(例如 GPU 驱动程序)的工作方式,Valgrind 很容易出现误报。基本上,这些驱动程序通过 BIOS 设置的用户 space(虚拟 RAM)访问 GPU 的内存(甚至 寄存器 )(这是 POSIX mmap at工作)。这样,驱动程序可以通过任意地址访问设备的寄存器,就像任何其他变量一样。
重点是某些设备的寄存器仅供读取。例如,它们可以反映设备的某些状态。因此,只有设备有理由写入它们(即使 CPU 尝试这样做,它也会失败)。大多数情况下,它会在开机时在内部执行此操作,并且有时会在状态更改时执行此操作,并在设置映射时向用户 space 反映。本质上,这些是纯粹的易变变量......甚至比通常的线程到线程概念更易变,顺便说一下,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 报告的内容)。由于版本更改,您可能还必须在每次更新驱动程序时更新它们,但我想您可以使用基本通配符来避免这种情况。
查看 here 了解有关此 Valgrind 功能的更多信息。