forked from osmocom/wireshark
Qt: fix hang on exiting Qt while loading capture file
testCaptureFileClose can also be invoked while reading an existing capture file (the original comment only applied to GTK+, not Qt). When the user quits Wireshark while reading an offline pcap, this could result in a confusing "Unsaved packets" dialog. Fix this by checking the actual capture session state. After fixing this, the next issue is that cf_close trips on an assertion ("cf->state != FILE_READ_IN_PROGRESS"). To address this problem, do not close the capture file immediately, but signal to the reader (cf_read) that this should be done (similar to the quit logic in GTK+). Bug: 13563 Change-Id: I12d4b813557bf354199320df2ed8609070fdc58a Reviewed-on: https://code.wireshark.org/review/22096 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Peter Wu <peter@lekensteyn.nl>
This commit is contained in:
parent
6462560b30
commit
800a856fb4
18
file.c
18
file.c
|
@ -541,6 +541,7 @@ cf_read(capture_file *cf, gboolean reloading)
|
|||
volatile gboolean create_proto_tree;
|
||||
guint tap_flags;
|
||||
gboolean compiled;
|
||||
volatile gboolean is_read_aborted = FALSE;
|
||||
|
||||
/* Compile the current display filter.
|
||||
* We assume this will not fail since cf->dfilter is only set in
|
||||
|
@ -642,6 +643,13 @@ cf_read(capture_file *cf, gboolean reloading)
|
|||
}
|
||||
}
|
||||
|
||||
if (cf->state == FILE_READ_ABORTED) {
|
||||
/* Well, the user decided to exit Wireshark. Break out of the
|
||||
loop, and let the code below (which is called even if there
|
||||
aren't any packets left to read) exit. */
|
||||
is_read_aborted = TRUE;
|
||||
break;
|
||||
}
|
||||
if (cf->stop_flag) {
|
||||
/* Well, the user decided to abort the read. He/She will be warned and
|
||||
it might be enough for him/her to work with the already loaded
|
||||
|
@ -717,6 +725,16 @@ cf_read(capture_file *cf, gboolean reloading)
|
|||
packet_list_select_first_row();
|
||||
}
|
||||
|
||||
if (is_read_aborted) {
|
||||
/*
|
||||
* Well, the user decided to exit Wireshark while reading this *offline*
|
||||
* capture file (Live captures are handled by something like
|
||||
* cf_continue_tail). Clean up accordingly.
|
||||
*/
|
||||
cf_close(cf);
|
||||
return CF_READ_ABORTED;
|
||||
}
|
||||
|
||||
if (cf->stop_flag) {
|
||||
simple_message_box(ESD_TYPE_WARN, NULL,
|
||||
"The remaining packets in the file were discarded.\n"
|
||||
|
|
|
@ -1030,6 +1030,10 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
|||
exit(0);
|
||||
}
|
||||
wsApp->quit();
|
||||
// When the main loop is not yet running (i.e. when openCaptureFile is
|
||||
// executing in wireshark-qt.cpp), the above quit action has no effect.
|
||||
// Schedule a quit action for the next execution of the main loop.
|
||||
QMetaObject::invokeMethod(wsApp, "quit", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
// XXX On windows the drag description is "Copy". It should be "Open" or
|
||||
|
@ -1783,19 +1787,17 @@ bool MainWindow::testCaptureFileClose(QString before_what, FileCloseContext cont
|
|||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
if (capture_file_.capFile()->state == FILE_READ_IN_PROGRESS) {
|
||||
/* This is true if we're reading a capture file *or* if we're doing
|
||||
a live capture. If we're reading a capture file, the main loop
|
||||
is busy reading packets, and only accepting input from the
|
||||
progress dialog, so we can't get here, so this means we're
|
||||
doing a capture. */
|
||||
capture_in_progress = true;
|
||||
/*
|
||||
* This (FILE_READ_IN_PROGRESS) is true if we're reading a capture file
|
||||
* *or* if we're doing a live capture. From the capture file itself we
|
||||
* cannot differentiate the cases, so check the current capture session.
|
||||
*/
|
||||
capture_in_progress = captureSession()->state != CAPTURE_STOPPED;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (prefs.gui_ask_unsaved) {
|
||||
if (cf_has_unsaved_data(capture_file_.capFile()) ||
|
||||
(capture_in_progress && capture_file_.capFile()->count > 0))
|
||||
{
|
||||
if (cf_has_unsaved_data(capture_file_.capFile())) {
|
||||
QMessageBox msg_dialog;
|
||||
QString question;
|
||||
QString infotext;
|
||||
|
@ -1893,7 +1895,9 @@ bool MainWindow::testCaptureFileClose(QString before_what, FileCloseContext cont
|
|||
captureStop();
|
||||
#endif
|
||||
/* Save the file and close it */
|
||||
if (saveCaptureFile(capture_file_.capFile(), true) == false)
|
||||
// XXX if no packets were captured, any unsaved comments set by
|
||||
// the user are silently discarded because capFile() is null.
|
||||
if (capture_file_.capFile() && saveCaptureFile(capture_file_.capFile(), true) == false)
|
||||
return false;
|
||||
do_close_file = true;
|
||||
} else if(msg_dialog.clickedButton() == discard_button) {
|
||||
|
@ -1913,12 +1917,27 @@ bool MainWindow::testCaptureFileClose(QString before_what, FileCloseContext cont
|
|||
do_close_file = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Are we done with this file and should we close the file?
|
||||
*/
|
||||
if (do_close_file) {
|
||||
#ifdef HAVE_LIBPCAP
|
||||
/* If there's a capture in progress, we have to stop the capture
|
||||
and then do the close. */
|
||||
if (capture_in_progress)
|
||||
captureStop();
|
||||
else if (capture_file_.capFile() && capture_file_.capFile()->state == FILE_READ_IN_PROGRESS) {
|
||||
/*
|
||||
* When an offline capture is being read, mark it as aborted.
|
||||
* cf_read will be responsible for actually closing the capture.
|
||||
*
|
||||
* We cannot just invoke cf_close here since cf_read is up in the
|
||||
* call chain. (update_progress_dlg can end up processing the Quit
|
||||
* event from the user which then ends up here.)
|
||||
*/
|
||||
capture_file_.capFile()->state = FILE_READ_ABORTED;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
/* captureStop() will close the file if not having any packets */
|
||||
if (capture_file_.capFile() && context != Restart && context != Reload)
|
||||
|
|
Loading…
Reference in New Issue