diff options
-rw-r--r-- | epan/dissectors/packet-ethertype.c | 3 | ||||
-rw-r--r-- | epan/dissectors/packet-frame.c | 3 | ||||
-rw-r--r-- | epan/emem.c | 14 | ||||
-rw-r--r-- | epan/exceptions.h | 6 | ||||
-rw-r--r-- | epan/packet.c | 6 | ||||
-rw-r--r-- | file.c | 64 |
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); @@ -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 */ |