SIGSEGV after dive computer download

Linus Torvalds torvalds at
Tue Sep 17 07:40:40 UTC 2013

On Tue, Sep 17, 2013 at 10:19 AM, Linus Torvalds
<torvalds at> wrote:
> Oh, well. On to doing this the hard way, using valgrind..

Ok, with valgrind even current master "works", which actually makes
sense if it's an allocation issue (valgrind takes over memory
allocators and replaces them with its own).

But valgrind spits out a *lot* of error messages about bad memory
accesses.  Most of the early ones seem to be about some strings
allocated with "strdup()", and then subsequent 4-byte reads that
straddle the end, which is probably fine (my guess is that something
just does "int" accesses to find the zero byte, knowing that the
allocation is int-aligned). So you see lots of messages like

    Invalid read of size 4
    Address 0xea0661c is 44 bytes inside a block of size 45 alloc'd

which I'd ignore. But then we get to the meat of the data:

==12441== Invalid read of size 8
==12441==    at 0x46CD7C: WeightModel::data(QModelIndex const&, int)
const (models.cpp:402)
==12441==    by 0x30D7B57BE4:
QModelIndex const&) const (in /usr/lib64/
==12441==    by 0x30D7B56D6B: QStyledItemDelegate::paint(QPainter*,
QStyleOptionViewItem const&, QModelIndex const&) const (in
==12441==    by 0x30D7AE5840: ??? (in /usr/lib64/
==12441==    by 0x30D7AEEE70: QTableView::paintEvent(QPaintEvent*) (in
==12441==    by 0x30D7617903: QWidget::event(QEvent*) (in
==12441==    by 0x30D79B3CDD: QFrame::event(QEvent*) (in
==12441==    by 0x30D7AC1B22:
QAbstractItemView::viewportEvent(QEvent*) (in
==12441==    by 0x30D6F7A3D5:
QEvent*) (in /usr/lib64/
==12441==    by 0x30D75C84BB:
QApplicationPrivate::notify_helper(QObject*, QEvent*) (in
==12441==    by 0x30D75CEA9F: QApplication::notify(QObject*, QEvent*)
(in /usr/lib64/
==12441==    by 0x30D6F7A26C:
QCoreApplication::notifyInternal(QObject*, QEvent*) (in
==12441==  Address 0x1f73fb18 is 424 bytes inside a block of size 632 free'd
==12441==    at 0x4A074C4: free (in
==12441==    by 0x42A0D2: delete_single_dive (divelist.c:903)
==12441==    by 0x42A632: process_dives (divelist.c:1105)
==12441==    by 0x48F45F: DownloadThread::run()
==12441==    by 0x30D6E7AD0E: ??? (in /usr/lib64/
==12441==    by 0x30CFA07C52: start_thread (in /usr/lib64/
==12441==    by 0x30CEEF5D3C: clone (in /usr/lib64/

this is the kind of thing that causes SIGSEGV's - something accesses
free'd data.  And you can see where it was free'd: in
"delete_single_dive()" called from process_dives(), called from the
downloading thread.

And the user is that WeightModel thing. So this matches the SIGSEGV exactly.

And the reason it only happens with multiple dive computers is that
the "delete_single_dive()" thing only happens when dives get merged
due to being duplicate. So Tomaz, you may have a hard time reproducing
this, although even with asingle dive computer you could do this:

 - download all dives from that dive computer, save and exit
 - edit the XML file for the last dive to have a *different* dive
computer ID and dive ID.
 - re-download from the same dive computer, and now subsurface should
consider that last dive to have two different dive computers (that
just happen to have the same data).

but maybe you don't even need to do this with these hints. I'm
attaching the whole valgrind log (I'm not sure you've ever used
valgrind - it's very powerful, but it can have those annoying false
positives when you have things that optimize memory accesses knowing
that they are safe due to alignment things). The valgrind output isn't
beautiful, but it's quite useful once you kind of wrap your head
around the format.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: vg-file
Type: application/octet-stream
Size: 101747 bytes
Desc: not available
URL: <>

More information about the subsurface mailing list