Skip to content

Commit 7904d4d

Browse files
authored
Added memory test analysis plugin (#3307)
1 parent 9e8fa18 commit 7904d4d

File tree

5 files changed

+82
-14
lines changed

5 files changed

+82
-14
lines changed

plaso/analysis/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from plaso.analysis import nsrlsvr
88
from plaso.analysis import sessionize
99
from plaso.analysis import tagging
10+
from plaso.analysis import test_memory
1011
from plaso.analysis import unique_domains_visited
1112
from plaso.analysis import viper
1213
from plaso.analysis import virustotal

plaso/analysis/interface.py

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class AnalysisPlugin(object):
2121
# explains the nature of the plugin easily. It also needs to be unique.
2222
NAME = 'analysis_plugin'
2323

24+
# Flag to indicate the analysis is for testing purposes only.
25+
TEST_PLUGIN = False
26+
2427
def __init__(self):
2528
"""Initializes an analysis plugin."""
2629
super(AnalysisPlugin, self).__init__()

plaso/analysis/manager.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,13 @@ def GetAllPluginInformation(cls):
5252
"""
5353
results = []
5454
for plugin_class in cls._plugin_classes.values():
55-
plugin_object = plugin_class()
56-
# TODO: Use a specific description variable, not the docstring.
57-
doc_string, _, _ = plugin_class.__doc__.partition('\n')
58-
type_string = cls._PLUGIN_TYPE_STRINGS.get(plugin_object.plugin_type)
59-
information_tuple = (plugin_object.NAME, doc_string, type_string)
60-
results.append(information_tuple)
55+
if not plugin_class.TEST_PLUGIN:
56+
plugin_object = plugin_class()
57+
# TODO: Use a specific description variable, not the docstring.
58+
doc_string, _, _ = plugin_class.__doc__.partition('\n')
59+
type_string = cls._PLUGIN_TYPE_STRINGS.get(plugin_object.plugin_type)
60+
information_tuple = (plugin_object.NAME, doc_string, type_string)
61+
results.append(information_tuple)
6162

6263
return sorted(results)
6364

plaso/analysis/test_memory.py

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# -*- coding: utf-8 -*-
2+
"""Analysis plugin for testing exceeding memory consumption."""
3+
4+
from __future__ import unicode_literals
5+
6+
from plaso.analysis import interface
7+
from plaso.analysis import manager
8+
from plaso.containers import reports
9+
10+
11+
class TestMemoryAnalysisPlugin(interface.AnalysisPlugin):
12+
"""Analysis plugin for testing memory consumption."""
13+
14+
NAME = 'test_memory'
15+
16+
TEST_PLUGIN = True
17+
18+
def __init__(self):
19+
"""Initializes an analysis plugin for testing memory consumption."""
20+
super(TestMemoryAnalysisPlugin, self).__init__()
21+
self._objects = []
22+
23+
def CompileReport(self, mediator):
24+
"""Compiles an analysis report.
25+
26+
Args:
27+
mediator (AnalysisMediator): mediates interactions between
28+
analysis plugins and other components, such as storage and dfvfs.
29+
30+
Returns:
31+
AnalysisReport: analysis report.
32+
"""
33+
return reports.AnalysisReport(
34+
plugin_name=self.NAME, text='TestMemory report')
35+
36+
def ExamineEvent(self, mediator, event, event_data, event_data_stream):
37+
"""Analyzes an event.
38+
39+
Args:
40+
mediator (AnalysisMediator): mediates interactions between
41+
analysis plugins and other components, such as storage and dfvfs.
42+
event (EventObject): event.
43+
event_data (EventData): event data.
44+
event_data_stream (EventDataStream): event data stream.
45+
"""
46+
self._objects.append(list(range(1024)))
47+
48+
49+
manager.AnalysisPluginManager.RegisterPlugin(TestMemoryAnalysisPlugin)

plaso/multi_processing/psort.py

+22-8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from plaso.engine import zeromq_queue
1313
from plaso.lib import bufferlib
1414
from plaso.lib import definitions
15+
from plaso.lib import errors
1516
from plaso.multi_processing import analysis_process
1617
from plaso.multi_processing import engine as multi_process_engine
1718
from plaso.multi_processing import logger
@@ -916,7 +917,9 @@ def AnalyzeEvents(
916917
if not analysis_plugins:
917918
return
918919

920+
abort_kill = False
919921
keyboard_interrupt = False
922+
queue_full = False
920923

921924
self._analysis_plugins = {}
922925
self._data_location = data_location
@@ -952,15 +955,20 @@ def AnalyzeEvents(
952955

953956
self._status = definitions.STATUS_INDICATOR_FINALIZING
954957

958+
except errors.QueueFull:
959+
queue_full = True
960+
self._abort = True
961+
955962
except KeyboardInterrupt:
956963
keyboard_interrupt = True
957964
self._abort = True
958965

959-
self._processing_status.aborted = True
960-
if self._status_update_callback:
961-
self._status_update_callback(self._processing_status)
962-
963966
finally:
967+
if self._abort:
968+
self._processing_status.aborted = True
969+
if self._status_update_callback:
970+
self._status_update_callback(self._processing_status)
971+
964972
storage_writer.WriteSessionCompletion(aborted=self._abort)
965973

966974
storage_writer.Close()
@@ -970,12 +978,18 @@ def AnalyzeEvents(
970978
# so we include the storage sync to disk in the status updates.
971979
self._StopStatusUpdateThread()
972980

973-
try:
974-
self._StopAnalysisProcesses(abort=self._abort)
981+
if queue_full:
982+
# TODO: handle abort on queue full more elegant.
983+
abort_kill = True
984+
else:
985+
try:
986+
self._StopAnalysisProcesses(abort=self._abort)
975987

976-
except KeyboardInterrupt:
977-
keyboard_interrupt = True
988+
except KeyboardInterrupt:
989+
keyboard_interrupt = True
990+
abort_kill = True
978991

992+
if abort_kill:
979993
self._AbortKill()
980994

981995
# The abort can leave the main process unresponsive

0 commit comments

Comments
 (0)