Hi all,
I played a little with Valgrind:
valgrind --vgdb=yes --vgdb-error=0 ./vdr ... and in gdb, (gdb) target remote |vgdb
This seems to give me a false alarm for cRecording::cRecording():
Program received signal SIGTRAP, Trace/breakpoint trap. 0x0811951a in cRecording::cRecording (this=0xbee4d958, FileName=0x0) at recording.c:801 801 if (*(fileName + strlen(fileName) - 1) == '/')
The machine code is doing some magic after the strdup() on the previous line. I suspect that it is gcc that is performing strlen() with some black magic that trips this warning:
==3212== Invalid read of size 4 ==3212== at 0x811951A: cRecording::cRecording(char const*) (recording.c:801) ==3212== by 0x80CEF77: cDvbPlayer::cDvbPlayer(char const*, bool) (dvbplayer.c:268) ==3212== Address 0x4454004 is 76 bytes inside a block of size 78 alloc'd ==3212== at 0x4028308: malloc (vg_replace_malloc.c:263) ==3212== by 0x4315E1F: strdup (strdup.c:43) ==3212== by 0x81194FE: cRecording::cRecording(char const*) (recording.c:800)
Then I got and fixed many warnings in Softdevice, which forgot to initialize some class members in constructors. Finally, I got a real warning for VDR:
==3212== Conditional jump or move depends on uninitialised value(s) ==3212== at 0x4029654: __GI_strcmp (mc_replace_strmem.c:712) ==3212== by 0x813ACD8: cSkinLCARSDisplayReplay::DrawTrack() (skinlcars.c:1786) ==3212== by 0x813AE9F: cSkinLCARSDisplayReplay::Flush() (skinlcars.c:1861) ==3212== by 0x80FCA55: cReplayControl::ShowProgress(bool) (menu.c:4670) ==3212== by 0x80FCBF7: cReplayControl::ShowTimed(int) (menu.c:4583) ==3212== by 0x80FCDEF: cReplayControl::cReplayControl(bool) (menu.c:4510) ==3212== by 0x80AC745: main (vdr.c:1307)
"(gdb) monitor get_vbits" tells me that all of lastTrackId is uninitialized:
(gdb) up #1 0x0813acd9 in cSkinLCARSDisplayReplay::DrawTrack ( this=this@entry=0x457c3a0) at skinlcars.c:1786 1786 if (!Track && *lastTrackId.description || Track && strcmp(lastTrackId.description, Track->description)) { (gdb) p lastTrackId $27 = {id = 0, language = "\000\000\000\000\000\000\000", description = '\000' <repeats 31 times>} (gdb) p &lastTrackId $28 = (tTrackId *) 0x457c434 (gdb) p sizeof lastTrackId $29 = 42 (gdb) monitor get_vbits 0x457c434 42 ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffff
BTW, !Track && x || Track && y should IMO be simpler written Track ? y : x.
It looks like a memset() is missing from the cSkinLCARSDisplayReplay constructor. cSkinLCARSDisplayChannel::cSkinLCARSDisplayChannel() is doing the right thing:
memset(&lastTrackId, 0, sizeof(lastTrackId));
Adding the memset() made this message go away. (Patch attached.)
The next problem is this one, which I get every time by pressing Play, Pause, Menu, Recordings after startup:
==3601== Conditional jump or move depends on uninitialised value(s) ==3601== at 0x810C0DB: cRect::Intersected(cRect const&) const (osd.h:411) ==3601== by 0x810E3D1: cPixmapMemory::DrawRectangle(cRect const&, unsigned int) (osd.c:1333) ==3601== by 0x810AA0B: cOsd::DrawRectangle(int, int, int, int, unsigned int) (osd.c:1922) ==3601== by 0x8130482: cSkinLCARSDisplayMenu::Clear() (skinlcars.c:1463) ==3601== by 0x810651F: cOsdMenu::Display() (osdbase.c:223) ==3601== by 0x80FA3D1: cMenuMain::Set() (menu.c:3432) ==3601== by 0x80FA9FD: cMenuMain::cMenuMain(eOSState, bool) (menu.c:3376) ==3601== by 0x80AC21B: main (vdr.c:1078)
According to "monitor get_vbits", the cRect is totally uninitialized.
Program received signal SIGTRAP, Trace/breakpoint trap. 0x0810c0db in IsEmpty (this=0xbeba08a0) at osd.h:411 411 bool IsEmpty(void) const { return Width() <= 0 || Height() <= 0; } (gdb) up #1 cRect::Intersected (this=this@entry=0xbeba08a0, Rect=...) at osd.c:912 912 if (!IsEmpty() && !Rect.IsEmpty()) { (gdb) up #2 0x0810e3d2 in cPixmapMemory::DrawRectangle (this=0x6d3fe78, Rect=..., Color=2566914048) at osd.c:1333 1333 cRect r = Rect.Intersected(DrawPort().Size());
As far as I can tell, the entirely uninitialized cRect is being passed as the Rect parameter to cPixmapMemory::DrawRectangle(). Unfortunately, gdb cannot show me the stack above that. It would seem to me that cSkinLCARSDisplayMenu::Clear() is passing uninitialized bounds to cOsd::DrawRectangle(), which will lead to funny values like this:
(gdb) p *this $31 = {point = {x = 1418239204, y = 0}, size = {width = -1379480940, height = 201}, static Null = {point = {x = 0, y = 0}, size = {width = 0, height = 0}, static Null = <same as static member of an already seen type>}}
As a workaround, I guess that I will be switching away from the LCARS skin for now. I got into this exercise because vdr sometimes crashed when I pressed the Recordings or Menu button when using the LCARS skin.
I am also attaching my patch against softdevice CVS, in case someone finds it useful. I was unable to figure out how to clear the garbage at the bottom of the OSD screen. It goes away if the dfb:mgatv video display area is high enough (4:3 video instead of 16:9).
Best regards,
Marko