From 6cb9354d6ea5160bc56374485db42608ac1b4424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Stucke?= Date: Mon, 9 Oct 2023 10:53:01 +0200 Subject: [PATCH] tracebacks from analysis exceptions are now logged tracebacks from analysis exceptions were printed to the command line but not logged, resulting in them not showing up in log files or the web GUI this only affected the old plugin base class but not the new base class / runner --- src/analysis/PluginBase.py | 25 ++++++++++++++++++------- src/helperFunctions/process.py | 6 ++++-- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/analysis/PluginBase.py b/src/analysis/PluginBase.py index 93a5e4920..3f6f2375f 100644 --- a/src/analysis/PluginBase.py +++ b/src/analysis/PluginBase.py @@ -1,4 +1,6 @@ -import ctypes # noqa: N999 +from __future__ import annotations # noqa: N999 + +import ctypes import logging import os from multiprocessing import Array, Manager, Queue, Value @@ -17,8 +19,11 @@ terminate_process_and_children, ) from helperFunctions.tag import TagColor -from objects.file import FileObject from plugins.base import BasePlugin +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from objects.file import FileObject META_KEYS = { 'tags', @@ -47,7 +52,7 @@ def sanitize_processed_analysis(processed_analysis_entry: dict) -> dict: class PluginInitException(Exception): # noqa: N818 - def __init__(self, *args, plugin: 'AnalysisBasePlugin'): + def __init__(self, *args, plugin: AnalysisBasePlugin): self.plugin: AnalysisBasePlugin = plugin super().__init__(*args) @@ -202,7 +207,7 @@ def timeout_happened(process): def worker_processing_with_timeout(self, worker_id, next_task: FileObject): result = self.manager.list() - process = ExceptionSafeProcess(target=self.process_next_object, args=(next_task, result)) + process = ExceptionSafeProcess(target=self.process_next_object, args=(next_task, result), reraise=False) start = time() process.start() process.join(timeout=self.TIMEOUT) @@ -214,7 +219,8 @@ def worker_processing_with_timeout(self, worker_id, next_task: FileObject): if self.timeout_happened(process): result_fo = self._handle_failed_analysis(next_task, process, worker_id, 'Timeout') elif process.exception: - result_fo = self._handle_failed_analysis(next_task, process, worker_id, 'Exception') + _, trace = process.exception + result_fo = self._handle_failed_analysis(next_task, process, worker_id, 'Exception', trace=trace) else: result_fo = result.pop() logging.debug(f'Worker {worker_id}: Finished {self.NAME} analysis on {next_task.uid}') @@ -233,10 +239,15 @@ def _update_duration_stats(self, duration): if self.analysis_stats_count.value < self.ANALYSIS_STATS_LIMIT: self.analysis_stats_count.value += 1 - def _handle_failed_analysis(self, fw_object, process, worker_id, cause: str): + def _handle_failed_analysis( # noqa: PLR0913 + self, fw_object, process, worker_id, cause: str, trace: str | None = None + ): terminate_process_and_children(process) fw_object.analysis_exception = (self.NAME, f'{cause} occurred during analysis') - logging.error(f'Worker {worker_id}: {cause} during analysis {self.NAME} on {fw_object.uid}') + message = f'Worker {worker_id}: {cause} during analysis {self.NAME} on {fw_object.uid}' + if trace: + message += f':\n{trace}' + logging.error(message) return fw_object diff --git a/src/helperFunctions/process.py b/src/helperFunctions/process.py index 3b7d1edbb..3eb6bfe85 100644 --- a/src/helperFunctions/process.py +++ b/src/helperFunctions/process.py @@ -72,10 +72,11 @@ class ExceptionSafeProcess(Process): .. _Python docs: https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Process """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, reraise: bool = True, **kwargs): super().__init__(*args, **kwargs) self._receive_pipe, self._send_pipe = Pipe() self._exception = None + self._reraise = reraise def run(self): """ @@ -88,7 +89,8 @@ def run(self): except Exception as exception: trace = traceback.format_exc() self._send_pipe.send((exception, trace)) - raise exception + if self._reraise: + raise exception @property def exception(self) -> tuple[Exception, str] | None: