aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>2007-01-15 05:16:13 +0000
committerulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>2007-01-15 05:16:13 +0000
commit7a691a2473a80490cb5ceaf0bace0986b1bd8842 (patch)
tree65a493d1fa5798cb206fb7edb6ef6cdf72973b05
parentbe64b743e8bd34cc7e24a4fb594e91d0472efa0c (diff)
instead of simply doing an assert when running out of memory in emem, throw a new OutOfMemoryError Exception, so file.c can show at least a better explanation to the user before Wireshark terminates
XXX - to prevent a busy wait, I need a portable way to wait for a short time period, like Sleep() for Windows git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@20437 f5534014-38df-0310-8fa8-9805f1628bb7
-rw-r--r--epan/dissectors/packet-ethertype.c3
-rw-r--r--epan/dissectors/packet-frame.c3
-rw-r--r--epan/emem.c14
-rw-r--r--epan/exceptions.h6
-rw-r--r--epan/packet.c6
-rw-r--r--file.c64
6 files changed, 89 insertions, 7 deletions
diff --git a/epan/dissectors/packet-ethertype.c b/epan/dissectors/packet-ethertype.c
index d06a167deb..b4ded722b6 100644
--- a/epan/dissectors/packet-ethertype.c
+++ b/epan/dissectors/packet-ethertype.c
@@ -216,6 +216,9 @@ ethertype(guint16 etype, tvbuff_t *tvb, int offset_after_etype,
else. */
RETHROW;
}
+ CATCH(OutOfMemoryError) {
+ RETHROW;
+ }
CATCH_ALL {
/* Somebody threw an exception other than BoundsError, which
means that a dissector was found, so we don't need to
diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c
index 65d50b3249..d3a695dcd8 100644
--- a/epan/dissectors/packet-frame.c
+++ b/epan/dissectors/packet-frame.c
@@ -313,6 +313,9 @@ dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
}
#endif
}
+ CATCH(OutOfMemoryError) {
+ RETHROW;
+ }
CATCH_ALL {
show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
}
diff --git a/epan/emem.c b/epan/emem.c
index 88945a8387..f4945d8f16 100644
--- a/epan/emem.c
+++ b/epan/emem.c
@@ -288,7 +288,9 @@ emem_create_chunk(emem_chunk_t **free_list) {
/* XXX - is MEM_COMMIT|MEM_RESERVE correct? */
npc->buf = VirtualAlloc(NULL, EMEM_PACKET_CHUNK_SIZE,
MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
- g_assert(npc->buf != NULL);
+ if(npc->buf == NULL) {
+ THROW(OutOfMemoryError);
+ }
buf_end = npc->buf + EMEM_PACKET_CHUNK_SIZE;
/* Align our guard pages on page-sized boundaries */
@@ -308,7 +310,10 @@ emem_create_chunk(emem_chunk_t **free_list) {
#elif defined(USE_GUARD_PAGES)
npc->buf = mmap(NULL, EMEM_PACKET_CHUNK_SIZE,
PROT_READ|PROT_WRITE, ANON_PAGE_MODE, ANON_FD, 0);
- g_assert(npc->buf != MAP_FAILED);
+ if(npc->buf == MAP_FAILED) {
+ /* XXX - what do we have to cleanup here? */
+ THROW(OutOfMemoryError);
+ }
buf_end = npc->buf + EMEM_PACKET_CHUNK_SIZE;
/* Align our guard pages on page-sized boundaries */
@@ -325,11 +330,14 @@ emem_create_chunk(emem_chunk_t **free_list) {
npc->free_offset = npc->free_offset_init;
#else /* Is there a draft in here? */
+ npc->buf = malloc(EMEM_PACKET_CHUNK_SIZE);
+ if(npc->buf == NULL) {
+ THROW(OutOfMemoryError);
+ }
npc->amount_free_init = EMEM_PACKET_CHUNK_SIZE;
npc->amount_free = npc->amount_free_init;
npc->free_offset_init = 0;
npc->free_offset = npc->free_offset_init;
- npc->buf = g_malloc(EMEM_PACKET_CHUNK_SIZE);
#endif /* USE_GUARD_PAGES */
}
}
diff --git a/epan/exceptions.h b/epan/exceptions.h
index b087f01a7e..acf9b78a27 100644
--- a/epan/exceptions.h
+++ b/epan/exceptions.h
@@ -67,6 +67,12 @@
**/
#define ScsiBoundsError 5
+/**
+ Running out of memory.
+ A dissector tried to allocate memory but that failed.
+**/
+#define OutOfMemoryError 6
+
/* Usage:
*
diff --git a/epan/packet.c b/epan/packet.c
index 50f3e34cee..8b039fbe9a 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -338,6 +338,9 @@ dissect_packet(epan_dissect_t *edt, union wtap_pseudo_header *pseudo_header,
g_assert_not_reached();
}
}
+ CATCH(OutOfMemoryError) {
+ RETHROW;
+ }
ENDTRY;
fd->flags.visited = 1;
@@ -546,6 +549,9 @@ call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb,
*/
ret = tvb_length(tvb);
}
+ CATCH(OutOfMemoryError) {
+ RETHROW;
+ }
ENDTRY;
col_set_writable(pinfo->cinfo, save_writable);
diff --git a/file.c b/file.c
index db69e84852..1c23d49fbf 100644
--- a/file.c
+++ b/file.c
@@ -363,6 +363,12 @@ cf_close(capture_file *cf)
cf_callback_invoke(cf_cb_file_closed, cf);
}
+/* an out of memory exception occured, wait for a user button press to exit */
+void outofmemory_cb(gpointer dialog, gint btn, gpointer data)
+{
+ main_window_exit();
+}
+
cf_read_status_t
cf_read(capture_file *cf)
{
@@ -481,7 +487,30 @@ cf_read(capture_file *cf)
hours even on fast machines) just to see that it was the wrong file. */
break;
}
- read_packet(cf, dfcode, data_offset);
+ TRY {
+ read_packet(cf, dfcode, data_offset);
+ }
+ CATCH(OutOfMemoryError) {
+ gpointer dialog;
+
+ dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "%sOut Of Memory!%s\n"
+ "\n"
+ "Sorry, but Wireshark has to terminate now!\n"
+ "\n"
+ "Some infos / workarounds can be found at:\n"
+ "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
+ simple_dialog_primary_start(), simple_dialog_primary_end());
+ /* we have to terminate, as we cannot recover from the memory error */
+ simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
+ while(1) {
+ main_window_update();
+ /* XXX - how to avoid a busy wait? */
+ /* Sleep(100); */
+ };
+ break;
+ }
+ ENDTRY;
}
/* Cleanup and release all dfilter resources */
@@ -617,9 +646,36 @@ cf_continue_tail(capture_file *cf, int to_read, int *err)
aren't any packets left to read) exit. */
break;
}
- if (read_packet(cf, dfcode, data_offset) != -1) {
- newly_displayed_packets++;
+ TRY{
+ if (read_packet(cf, dfcode, data_offset) != -1) {
+ newly_displayed_packets++;
+ }
+ }
+ CATCH(OutOfMemoryError) {
+ gpointer dialog;
+
+ dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "%sOut Of Memory!%s\n"
+ "\n"
+ "Sorry, but Wireshark has to terminate now!\n"
+ "\n"
+ "The capture file is not lost, it can be found at:\n"
+ "%s\n"
+ "\n"
+ "Some infos / workarounds can be found at:\n"
+ "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
+ simple_dialog_primary_start(), simple_dialog_primary_end(), cf->filename);
+ /* we have to terminate, as we cannot recover from the memory error */
+ simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
+ while(1) {
+ main_window_update();
+ /* XXX - how to avoid a busy wait? */
+ /* Sleep(100); */
+ };
+ packet_list_thaw();
+ return CF_READ_ABORTED;
}
+ ENDTRY;
to_read--;
}
@@ -691,7 +747,7 @@ cf_finish_tail(capture_file *cf, int *err)
aren't any packets left to read) exit. */
break;
}
- read_packet(cf, dfcode, data_offset);
+ read_packet(cf, dfcode, data_offset);
}
/* Cleanup and release all dfilter resources */