|
From: Jonathan M. <jma...@us...> - 2008-01-08 06:01:44
|
Hi all, After running valgrind on XBMC for Linux, we've hit a strange issue with an assignment to a bool. To simplify, the code is of the form: bool done(test > 3); It is my understanding (and this may well be what is in error ;) that this is essentially the same (ref http://www.cplusplus.com/doc/tutorial/variables.html) as: bool done = (test > 3); However, code in the first form causes valgrind to declare that usage of the variable done is use of an uninitialised variable, whereas code in the second form yields no complaints. The real code in question is the following: 34 bool needsToScroll(m_renderRect.Width() + 0.5f < m_textWidth); // 0.5f to deal with floating point rounding issues 35 if (m_scrolling && needsToScroll) 36 m_textLayout.RenderScrolling(m_renderRect.x1, m_renderRect.y1, m_label.angle, color, m_label.shadowColor, 0, m_renderRect.Width(), m_scrollInfo); 37 else 38 { 39 float posX = m_renderRect.x1; 40 DWORD align = 0; 41 if (!needsToScroll) 42 { // hack for right and centered multiline text, as GUITextLayout::Render() treats posX as the right hand 43 // or center edge of the text (see GUIFontTTF::DrawTextInternal), and this has already been taken care of 44 // in SetLabel(), but we wish to still pass the horizontal alignment info through (so that multiline text 45 // is aligned correctly), so we must undo the SetLabel() changes for horizontal alignment. 46 if (m_label.align & XBFONT_RIGHT) 47 posX += m_renderRect.Width(); 48 else if (m_label.align & XBFONT_CENTER_X) 49 posX += m_renderRect.Width() * 0.5f; 50 align = m_label.align & ~XBFONT_CENTER_Y; // ignore vertical alignment 51 } 52 m_textLayout.Render(posX, m_renderRect.y1, m_label.angle, color, m_label.shadowColor, align, m_renderRect.Width()); 53 } (note that m_scrolling is assigned in the constructor, so the needsToScroll variable is clearly the issue) and the output from valgrind relevant to this is: ==23316== Conditional jump or move depends on uninitialised value(s) ==23316== at 0x85D0CD9: CGUIListLabel::Render() (GUIListLabel.cpp:35) ==23316== by 0x85A8420: CGUIControl::DoRender(unsigned long) (GUIControl.cpp:115) ==23316== by 0x85CB4E9: CGUIListItemLayout::Render(CGUIListItem*, unsigned long, unsigned long) (GUIListItemLayout.cpp:144) ==23316== by 0x8595513: CGUIBaseContainer::RenderItem(float, float, CGUIListItem*, bool) (GUIBaseContainer.cpp:64) ==23316== by 0x85C5892: CGUIListContainer::Render() (GUIListContainer.cpp:89) ==23316== by 0x85A8420: CGUIControl::DoRender(unsigned long) (GUIControl.cpp:115) ==23316== by 0x859435D: CGUIBaseContainer::DoRender(unsigned long) (GUIBaseContainer.cpp:392) ==23316== by 0x85FBB8A: CGUIWindow::Render() (GUIWindow.cpp:456) ==23316== by 0x8600464: CGUIWindowManager::Render_Internal() (GUIWindowManager.cpp:409) ==23316== by 0x860169D: CGUIWindowManager::Render() (GUIWindowManager.cpp:402) ==23316== by 0x83147EE: CApplication::DoRender() (Application.cpp:2491) ==23316== by 0x8328C1D: CApplicationRenderer::Render(bool) (ApplicationRenderer.cpp:322) ==23316== ==23316== Conditional jump or move depends on uninitialised value(s) ==23316== at 0x85D0D85: CGUIListLabel::Render() (GUIListLabel.cpp:41) ==23316== by 0x85A8420: CGUIControl::DoRender(unsigned long) (GUIControl.cpp:115) ==23316== by 0x85CB4E9: CGUIListItemLayout::Render(CGUIListItem*, unsigned long, unsigned long) (GUIListItemLayout.cpp:144) ==23316== by 0x8595513: CGUIBaseContainer::RenderItem(float, float, CGUIListItem*, bool) (GUIBaseContainer.cpp:64) ==23316== by 0x85C5892: CGUIListContainer::Render() (GUIListContainer.cpp:89) ==23316== by 0x85A8420: CGUIControl::DoRender(unsigned long) (GUIControl.cpp:115) ==23316== by 0x859435D: CGUIBaseContainer::DoRender(unsigned long) (GUIBaseContainer.cpp:392) ==23316== by 0x85FBB8A: CGUIWindow::Render() (GUIWindow.cpp:456) ==23316== by 0x8600464: CGUIWindowManager::Render_Internal() (GUIWindowManager.cpp:409) ==23316== by 0x860169D: CGUIWindowManager::Render() (GUIWindowManager.cpp:402) ==23316== by 0x83147EE: CApplication::DoRender() (Application.cpp:2491) ==23316== by 0x8328C1D: CApplicationRenderer::Render(bool) (ApplicationRenderer.cpp:322) Your assessment of the issue would be greatly appreciated :) Cheers, Jonathan |
|
From: Nicholas N. <nj...@cs...> - 2008-01-08 08:05:45
|
On Tue, 8 Jan 2008, Jonathan Marshall wrote: > After running valgrind on XBMC for Linux, we've hit a strange issue > with an assignment to a bool. To simplify, the code is of the form: > > bool done(test > 3); > > It is my understanding (and this may well be what is in error ;) that > this is essentially the same (ref > http://www.cplusplus.com/doc/tutorial/variables.html) as: > > bool done = (test > 3); > > However, code in the first form causes valgrind to declare that usage > of the variable done is use of an uninitialised variable, whereas code > in the second form yields no complaints. I don't know C++ well enough to comment. But, although Valgrind reports files/functions/line-numbers in its error messages, it actually works at the binary level, so if you can compare the assembly code for the two versions that might prove instructive. Nick |
|
From: Andy \Axel\ B. <val...@th...> - 2008-01-09 10:12:11
|
On Tue, 2008-01-08 at 19:01 +1300, Jonathan Marshall wrote: > Hi all, > > After running valgrind on XBMC for Linux, we've hit a strange issue > with an assignment to a bool. To simplify, the code is of the form: > > bool done(test > 3); > > It is my understanding (and this may well be what is in error ;) that > this is essentially the same (ref > http://www.cplusplus.com/doc/tutorial/variables.html) as: > > bool done = (test > 3); > > However, code in the first form causes valgrind to declare that usage > of the variable done is use of an uninitialised variable, whereas code > in the second form yields no complaints. That document you references only uses, AFAICT, constant values/literals in the "Initialization of variables" section when talking about these alternative methods of specifying default values. "test > 3" is an expression, which may not be supported (the difference between initialization at compile time and initialization at runtime, perhaps?). Do you get different results from valgrind when you do: bool done; done = test > 3; "type identifier ( expr )" may be a syntax error that the compiler is not picking up on, but it must not be initializing the value either (or initializing it to something else (like the address of test?)), which results in the valgrind error about uninitialized branch condition. Just speculating here. -- Andy "Axel" Bakun <val...@th...> |
|
From: Jonathan M. <jma...@us...> - 2008-01-09 19:31:59
|
Thanks for the replies, I will check out the difference in ASM between the two situations to see if that can yield some more light on the situation. Constant vs variable initialisation would surely be a major "gotcha" in the C++ specs if this is indeed the case. The key point ofcourse is that the code actually works in it's current state, using the form bool done(test > 3); i.e. done is always initialized correctly according to the code that follows. This is what makes valgrind's complaint rather strange. Cheers, Jonathan - Hide quoted text - On Jan 9, 2008 11:11 PM, Andy Axel Bakun <val...@th...> wrote: > On Tue, 2008-01-08 at 19:01 +1300, Jonathan Marshall wrote: > > Hi all, > > > > After running valgrind on XBMC for Linux, we've hit a strange issue > > with an assignment to a bool. To simplify, the code is of the form: > > > > bool done(test > 3); > > > > It is my understanding (and this may well be what is in error ;) that > > this is essentially the same (ref > > http://www.cplusplus.com/doc/tutorial/variables.html) as: > > > > bool done = (test > 3); > > > > However, code in the first form causes valgrind to declare that usage > > of the variable done is use of an uninitialised variable, whereas code > > in the second form yields no complaints. > > That document you references only uses, AFAICT, constant values/literals > in the "Initialization of variables" section when talking about these > alternative methods of specifying default values. "test > 3" is an > expression, which may not be supported (the difference between > initialization at compile time and initialization at runtime, perhaps?). > > Do you get different results from valgrind when you do: > > bool done; > done = test > 3; > > "type identifier ( expr )" may be a syntax error that the compiler is > not picking up on, but it must not be initializing the value either (or > initializing it to something else (like the address of test?)), which > results in the valgrind error about uninitialized branch condition. > Just speculating here. > > -- > Andy "Axel" Bakun <val...@th...> > > > ------------------------------------------------------------------------- > Check out the new SourceForge.net Marketplace. > It's the best place to buy or sell services for > just about anything Open Source. > http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace > _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users > |
|
From: Andy \Axel\ B. <val...@th...> - 2008-01-11 08:34:56
|
On Thu, 2008-01-10 at 08:30 +1300, Jonathan Marshall wrote:
> Thanks for the replies,
>
> I will check out the difference in ASM between the two situations to
> see if that can yield some more light on the situation. Constant vs
> variable initialisation would surely be a major "gotcha" in the C++
> specs if this is indeed the case.
According to objdump -d, gcc 4.1.2 20070925 produces the exact same
series of instructions for the following three constructs:
bool done = (test > 3);
bool done(test > 3);
bool done; done = (test > 3);
So that was a useless suggestion, at least for this compiler. Sorry for
the wild goose chase.
|
|
From: Nicholas N. <nj...@cs...> - 2008-01-12 23:25:05
|
On Fri, 11 Jan 2008, Andy "Axel" Bakun wrote: >> I will check out the difference in ASM between the two situations to >> see if that can yield some more light on the situation. Constant vs >> variable initialisation would surely be a major "gotcha" in the C++ >> specs if this is indeed the case. > > According to objdump -d, gcc 4.1.2 20070925 produces the exact same > series of instructions for the following three constructs: > > bool done = (test > 3); > bool done(test > 3); > bool done; done = (test > 3); > > So that was a useless suggestion, at least for this compiler. Sorry for > the wild goose chase. If Valgrind is doing different things in the two cases then there must be some difference at the binary level. Could there be some static constructors involved that run at start-up, or something like that? Nick |
|
From: Andy \Axel\ B. <val...@th...> - 2008-01-13 08:39:22
Attachments:
dotests.sh
|
On Sun, 2008-01-13 at 10:24 +1100, Nicholas Nethercote wrote: > On Fri, 11 Jan 2008, Andy "Axel" Bakun wrote: > > >> I will check out the difference in ASM between the two situations to > >> see if that can yield some more light on the situation. Constant vs > >> variable initialisation would surely be a major "gotcha" in the C++ > >> specs if this is indeed the case. > > > > According to objdump -d, gcc 4.1.2 20070925 produces the exact same > > series of instructions for the following three constructs: > > > > bool done = (test > 3); > > bool done(test > 3); > > bool done; done = (test > 3); > > > > So that was a useless suggestion, at least for this compiler. Sorry for > > the wild goose chase. > > If Valgrind is doing different things in the two cases then there must be > some difference at the binary level. Could there be some static > constructors involved that run at start-up, or something like that? For the record, I didn't see any differences, but obviously Jonathan Marshall has. I did run all three versions compiled at all five optimization levels against both execution paths through memcheck and received no errors. gcc produces the exact same executable for all versions at the same optimization level (using sha1sum), so consistency is expected. Attached is the test script I used if someone wants to give it a try with some other combination of compiler, valgrind or platform. Do you have something different than these, Jonathan? $ g++ --version g++ (GCC) 4.1.2 20070925 (Red Hat 4.1.2-33) $ valgrind --version valgrind-3.2.3 $ uname -a Linux hex 2.6.23.9-85.fc8 #1 SMP Fri Dec 7 15:49:59 EST 2007 i686 athlon i386 GNU/Linux |