Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ctrl+Q while reading directories leads to segfault crash #122

Closed
stdedos opened this issue Feb 24, 2020 · 9 comments
Closed

Ctrl+Q while reading directories leads to segfault crash #122

stdedos opened this issue Feb 24, 2020 · 9 comments

Comments

@stdedos
Copy link

stdedos commented Feb 24, 2020

_usr_bin_qdirstat.1000.crash.tar.gz

I don't know if it's actionable, your call

@shundhammer
Copy link
Owner

I would really appreciate at least some context information.

From the backtrace of that attached file (what format is this? generated by some crash reporting tool?) I can guess that you terminated the program while it was still reading directories.

In general, the log file (`/tmp/qdirstat-$USER/qdirstat.log) is needed to do anything useful. In this case we can do without it, but for future bug reports, please add it.

Looks like i can reproduce this. Investigating.

@shundhammer shundhammer changed the title Ctrl+Q during long qdirstat does not stop+exit, crashes instead Ctrl+Q while reading directories leads to segfault crash Feb 24, 2020
@shundhammer
Copy link
Owner

Backtrace:

 #0  ?? ()
 #1  QDirStat::DirInfo::readJobFinished (this=0x24419a0, dir=0x24c3510) at DirInfo.cpp:708
 #2  QDirStat::DirInfo::readJobFinished (this=0x24c3510, dir=0x24c3510) at DirInfo.cpp:712
 #3  QDirStat::DirReadJob::~DirReadJob (this=0x24c36f0, __in_chrg=<optimized out>) at DirReadJob.cpp:46
 #4  QDirStat::LocalDirReadJob::~LocalDirReadJob (this=0x24c36f0, __in_chrg=<optimized out>) at DirReadJob.cpp:169
 #5  QDirStat::LocalDirReadJob::~LocalDirReadJob (this=0x24c36f0, __in_chrg=<optimized out>) at DirReadJob.cpp:171
 #6  qDeleteAll<QList<QDirStat::DirReadJob*>::const_iterator> (begin=..., end=...) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qalgorithms.h:317
 #7  qDeleteAll<QList<QDirStat::DirReadJob*> > (c=...) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qalgorithms.h:325
 #8  QDirStat::DirReadJobQueue::clear (this=0x1fee9f8) at DirReadJob.cpp:680
 #9  QDirStat::DirReadJobQueue::~DirReadJobQueue (this=0x1fee9f8, __in_chrg=<optimized out>) at DirReadJob.cpp:646
 #10 QDirStat::DirTree::~DirTree (this=0x1fee9e0, __in_chrg=<optimized out>) at DirTree.cpp:47
 #11 QDirStat::DirTree::~DirTree (this=0x1fee9e0, __in_chrg=<optimized out>) at DirTree.cpp:56
 #12 QDirStat::DirTreeModel::~DirTreeModel (this=0x1ff1530, __in_chrg=<optimized out>) at DirTreeModel.cpp:55
 #13 QDirStat::DirTreeModel::~DirTreeModel (this=0x1ff1530, __in_chrg=<optimized out>) at DirTreeModel.cpp:56
 #14 MainWindow::~MainWindow (this=0x1e9c8a0, __in_chrg=<optimized out>) at MainWindow.cpp:180
 #15 MainWindow::~MainWindow (this=0x1e9c8a0, __in_chrg=<optimized out>) at MainWindow.cpp:183
 #16 main (argc=1, argv=0x7ffd81c03858) at main.cpp:149

@stdedos
Copy link
Author

stdedos commented Feb 24, 2020

I would really appreciate at least some context information.

Apologies if that appeared short. Probably I should phrase it differently, but that is the context:

Maybe this

Ctrl+Q during long qdirstat does not stop+exit, crashes instead

should be

Ctrl+Q during long qdirstat scan operation does not stop+exit, crashes instead

that

From the backtrace of that attached file (what format is this? generated by some crash reporting tool?) I can guess that you terminated the program while it was still reading directories.

Apologies, I forgot to mention that. I've worked so far by "just" providing those files, so I forgot that they are not "just" core dumps. It's an Apport-crash file (from Xenial)

In general, the log file (`/tmp/qdirstat-$USER/qdirstat.log) is needed to do anything useful. In this case we can do without it, but for future bug reports, please add it.

They don't appear very informative, but you are right: qdirstat-logs-122.tar.gz

There you go

Looks like i can reproduce this. Investigating.

@shundhammer
Copy link
Owner

shundhammer commented Feb 24, 2020

This must have been a long-standing bug:

It was a chicken-egg problem while shutting down everything properly while directory reading was still in progress. The DirTree was destroyed; it first deleted all allocated objects, including all the FileInfo / DirInfo objects recursively. This makes all pointers to those objects invalid.

Then it was the turn of the DirReadJobQueue. Since it still contained DirReadJob objects, they were also all deleted, causing each one to do all the finishing work for the associated DirInfo object; but since those pointers were now invalid because the DirTree had already deleted the underlying objects, this caused the segfault.

The fix was to check the tree first if it is in the process of being destroyed and not do the finishing work for each DirReadJob's DirInfo; in fact, never even acess that DirInfo at all anymore.


For a short while I had thought about reversing the order of cleanup work in the DirTree destructor (which would have meant creating the DirReadJobQueue with new on the heap rather than having it as a sub-object in the DirTree). That would have worked, but it would also have been very wasteful since finishing a ReadJob means sending signals to the DirTree to go through the affected subtree and do quite extensive work there; this is pointless when the entire DirTree is being destroyed anyway, and it might also have potential for crashes in other places.

@shundhammer
Copy link
Owner

Stavros, this was a good catch. I wonder why nobody reported this before; this must go back a long time.

@stdedos
Copy link
Author

stdedos commented Feb 24, 2020

Stavros, this was a good catch. I wonder why nobody reported this before; this must go back a long time.

😄 thank you. I like to break things, and share my findings / ideas

@stdedos
Copy link
Author

stdedos commented Feb 24, 2020

So, now it doesn't crash alright; but close experience is "a bit weird" still.

Can you make it:

  • Not freeze
  • "Expire and countdown" read jobs/threads as it prepares to exit
  • Give some visual signal that app is exiting soon?

@shundhammer
Copy link
Owner

shundhammer commented Feb 24, 2020

Well, if reading directories takes so long that you might even wish to terminate the program before it's finished, it reads a lot of directories, so it creates a lot of objects. Shutting down means to free all those objects, calling each one's destructor in the process that in turn does some cleaning up. It's just some few instructions for each one, but when you have hundreds of thousands of them, this also accumulates.

How long does this shutdown take for you? Are we talking about some few seconds or longer? What is your estimate how long it takes?

@stdedos
Copy link
Author

stdedos commented Feb 24, 2020

Scratch that, I cannot replicate it anymore :/

Maybe I confused executed versions, or there were weird I/O calls that were slugging, idk ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants