通过valgrind运行SDL Linux多媒体应用程序,弹出的错误之一通常是基于未初始化值的条件跳转,但我无法在代码中查明问题。这看起来像是误报,但我对valgrind的输出感到困惑。
我的问题有两方面:1)我没有看到有条件的跳转,valgrind说它发生了,2)我没有看到有问题的分配在它所说的线上未初始化的价值来源。
以下是运行valgrind --track-origins=yes
:
126 ==10430== Conditional jump or move depends on uninitialised value(s)
127 ==10430== at 0x60F9135: getenv (getenv.c:84)
128 ==10430== by 0x6161485: tzset_internal (tzset.c:405)
129 ==10430== by 0x6161648: __tz_convert (tzset.c:624)
130 ==10430== by 0x406EC5: CLog::IIOCP_LogMessage(char const*, ...) (Log.cpp:80)
131 ==10430== by 0x41453A: ConnectionThread::Connect() (ConnectionThread.cpp:224)
132 ==10430== by 0x4149C5: ConnectionThread::DoRun() (ConnectionThread.cpp:318)
133 ==10430== by 0x41499F: ConnectionThread::IOClientThread(void*) (ConnectionThread.cpp:313)
134 ==10430== by 0x50D1B4F: start_thread (pthread_create.c:304)
135 ==10430== by 0x619F7BC: clone (clone.S:112)
136 ==10430== Uninitialised value was created by a stack allocation
137 ==10430== at 0x4057D0: Video::DrawGraphic() (video.cpp:49)
这是DrawGraphics方法:
void Video::DrawGraphic(void)
{
if (exp_timer)
{
if (MainSur != NULL)
{
SurBlit();
exp_timer = false;
}
else
{
printf("\nError in DrawGraphic: MainSur is NULL.\n");
}
FPS++;
if (SDL_GetTicks() - TicksReadPipe >= 1000)
{
ScrStrategy.OnReadPackets(connThread.GetPackets());
TicksReadPipe = SDL_GetTicks();
}
}
if (SDL_GetTicks() - CurrentTicks >= 1000)
{
CurrentTicks = SDL_GetTicks();
FPS = 0;
}
}
所有变量都是Video
类的成员,并在构造时分配。我在这里看不到任何堆栈分配。
这是getenv
函数(我们没有输入折叠的if-branch)。我的glibc版本为2.13-38+deb7u6_all.deb,函数位于usr/src/glibc/eglibc-2.13/stdlib/getenv.c
:
33 char *
34 getenv (name)
35 const char *name;
36 {
37 size_t len = strlen (name);
38 char **ep;
39 uint16_t name_start;
40
41 if (__environ == NULL || name[0] == '\0')
42 return NULL;
43
44 if (name[1] == '\0')
45 +-- 25 lines: {-------------------------------------------------------------
70 else
71 {
72 #if _STRING_ARCH_unaligned
73 name_start = *(const uint16_t *) name;
74 #else
75 name_start = (((const unsigned char *) name)[0]
76 | (((const unsigned char *) name)[1] << 8));
77 #endif
78 len -= 2;
79 name += 2;
80
81 for (ep = __environ; *ep != NULL; ++ep)
82 {
83 #if _STRING_ARCH_unaligned
84 uint16_t ep_start = *(uint16_t *) *ep;
85 #else
86 uint16_t ep_start = (((unsigned char *) *ep)[0]
87 | (((unsigned char *) *ep)[1] << 8));
88 #endif
89
90 if (name_start == ep_start && !strncmp (*ep + 2, name, len)
91 && (*ep)[len + 2] == '=')
92 return &(*ep)[len + 3];
93 }
94 }
95
96 return NULL;
97 }
我没有在第84行看到有条件的跳跃。
getenv
确实来自tzset_internal
tzset.c:405
,tzset_internal
本身来自__tz_convert
tzset.c:624
,所以我相信我查看的源与valgrind使用的调试符号相匹配。
我错过了什么,或者如果没有,为什么valgrind将我指向这些源行/块?