diff --git a/todo/done.txt b/todo/done.txt index d61fbe7f6..2ef833ee1 100644 --- a/todo/done.txt +++ b/todo/done.txt @@ -1,5 +1,13 @@ DONE: +o In an ideal world, Zenmap would not run out of memory and crash. + And we already have an entry for improving Zenmap's memory + consumption. But in the meantime, we should catch the error and + present a more useful error message/explanation so the user + understands the problem. This should reduce the number of + out-of-memory "crash reports" we get too. See + http://seclists.org/nmap-dev/2014/q2/298 + o Provide an option to send a comment in scan packet data for target network. Examples: --data-string "Scan conducted by Marc Reis from SecOps, extension 2147" or --data-string "pH33r my l3eT diff --git a/todo/nmap.txt b/todo/nmap.txt index b606af747..5b1a8ffe4 100644 --- a/todo/nmap.txt +++ b/todo/nmap.txt @@ -55,13 +55,6 @@ o GSOC 2014 student Jay will be looking at these items: commonly get error reports from people who load so many systems that Zenmap gives an out of memory error and crashes. For example, see this thread: http://seclists.org/nmap-dev/2014/q2/46 - o In an ideal world, Zenmap would not run out of memory and crash. - And we already have an entry for improving Zenmap's memory - consumption. But in the meantime, we should catch the error and - present a more useful error message/explanation so the user - understands the problem. This should reduce the number of - out-of-memory "crash reports" we get too. See - http://seclists.org/nmap-dev/2014/q2/298 o Consider using a binary decision diagram for --exclude list to make it more efficient for large exclude lists. See http://seclists.org/nmap-dev/2012/q4/420. diff --git a/zenmap/zenmapGUI/NmapOutputViewer.py b/zenmap/zenmapGUI/NmapOutputViewer.py index 3bde8ab94..9ab913e20 100644 --- a/zenmap/zenmapGUI/NmapOutputViewer.py +++ b/zenmap/zenmapGUI/NmapOutputViewer.py @@ -296,8 +296,11 @@ class NmapOutputViewer (gtk.VBox): def show_nmap_output(self, output): """Show the string (or unicode) output in the output display.""" - self.text_view.get_buffer().set_text(output) - self.apply_highlighting() + try: + self.text_view.get_buffer().set_text(output) + self.apply_highlighting() + except MemoryError: + self.show_large_output_message(self.command_execution) def set_command_execution(self, command): """Set the live running command whose output is shown by this display. @@ -310,6 +313,31 @@ class NmapOutputViewer (gtk.VBox): self.output_file_pointer = None self.refresh_output() + def show_large_output_message(self, command=None): + buf = self.text_view.get_buffer() + try: + running = (command is not None and command.scan_state() is True) + except: + running = False + complete = False + else: + complete = not running + if running: + buf.set_text("Warning: You have insufficient resources for Zenmap " + "to be able to display the complete output from Nmap here. \n" + "Zenmap will continue to run the scan to completion. However," + " some features of Zenmap might not work as expected.") + elif complete: + buf.set_text("Warning: You have insufficient resources for Zenmap " + "to be able to display the complete output from Nmap here. \n" + "The scan has completed. However, some features of Zenmap " + "might not work as expected.") + else: + buf.set_text("Warning: You have insufficient resources for Zenmap " + "to be able to display the complete output from Nmap here. \n" + "The scan has been stopped. Some features of Zenmap might not " + "work as expected.") + def refresh_output(self, widget=None): """Update the output from the latest output of the command associated with this view, as set by set_command_execution. It has no effect if no @@ -322,7 +350,13 @@ class NmapOutputViewer (gtk.VBox): # Seek to the end of the most recent read. self.command_execution.stdout_file.seek(self.output_file_pointer) pos = self.command_execution.stdout_file.tell() - new_output = self.command_execution.stdout_file.read() + + try: + new_output = self.command_execution.stdout_file.read() + except MemoryError: + self.show_large_output_message(self.command_execution) + return + self.output_file_pointer = self.command_execution.stdout_file.tell() # print "read %d -> %d %d" % ( # pos, self.output_file_pointer, len(new_output)) @@ -335,10 +369,14 @@ class NmapOutputViewer (gtk.VBox): buf = self.text_view.get_buffer() prev_end_mark = buf.create_mark( None, buf.get_end_iter(), left_gravity=True) - buf.insert(buf.get_end_iter(), new_output) - # Highlight the new text. - self.apply_highlighting( - buf.get_iter_at_mark(prev_end_mark), buf.get_end_iter()) + try: + buf.insert(buf.get_end_iter(), new_output) + # Highlight the new text. + self.apply_highlighting( + buf.get_iter_at_mark(prev_end_mark), buf.get_end_iter()) + except MemoryError: + self.show_large_output_message(self.command_execution) + return if at_end: # If we were already scrolled to the bottom, scroll back to the diff --git a/zenmap/zenmapGUI/ScanInterface.py b/zenmap/zenmapGUI/ScanInterface.py index d07e6a1e3..c7f8134f1 100644 --- a/zenmap/zenmapGUI/ScanInterface.py +++ b/zenmap/zenmapGUI/ScanInterface.py @@ -654,7 +654,10 @@ class ScanInterface(HIGVBox): warn_dialog.destroy() parsed.set_xml_is_temp(command.xml_is_temp) self.collect_umit_info(command, parsed) - parsed.nmap_output = command.get_output() + try: + parsed.nmap_output = command.get_output() + except MemoryError: + self.scan_result.scan_result_notebook.nmap_output.nmap_output.show_large_output_message(command) self.update_ui() self.scans_store.finish_running_scan(command, parsed)