# Buggy code
def HasActiveTasks(self):
    """Determines if there are active tasks.

    A task is considered abandoned if its last update exceeds the inactive time.

    Returns:
      bool: True if there are active tasks.
    """
    if not self._active_tasks:
        return False

    inactive_time = int(time.time() * 1000000) - self._TASK_INACTIVE_TIME

    for task in iter(self._tasks_processing.values()):
        # Use a local variable to improve performance.
        task_identifier = task.identifier
        if task.last_processing_time < inactive_time:
            del self._tasks_processing[task_identifier]
            self._abandoned_tasks[task_identifier] = task
            del self._active_tasks[task_identifier]

    return bool(self._active_tasks)


# Traceback (KeyError)
plaso - log2timeline version 1.5.0

Source path     : /data/images/2016-0945-00/2016-0945-00-HDD01.E01
Source type     : storage media image

Identifier      PID     Status          Sources         Events          File
Main            15282   running         124812 (0)      148935 (0)
Worker_00       15292   collecting      1903 (0)        3419 (0)        TSK:/Windows/System32/WindowsPowerShell/v1.0
Worker_01       15296   collecting      4843 (0)        10232 (0)       TSK:/Windows/System32/{
Worker_02       15300   collecting      6450 (0)        5009 (0)        TSK:/Windows/System32/SMI/Manifests
Worker_03       15304   collecting      2934 (0)        50431 (0)       TSK:/Windows/System32/wdi/{c4a3}
Worker_04       15308   collecting      2917 (0)        3460 (0)        TSK:/Windows/System32/{3D
Worker_05       15312   running         3820 (7)        9815 (4)        TSK:/Windows/System32/{3DA
Worker_06       15316   collecting      21192 (0)       3489 (0)      TSK:/Windows/System32/wdi/{8643c
Worker_07       15320   collecting      3495 (0)        7159 (0)        TSK:/Windows/System32/winevt/Logs
Worker_08       15324   collecting      21358 (0)       3350 (0)        TSK:/Windows/System32/wdi/perftrack
Worker_09       15328   collecting      2212 (0)        12994 (0)       TSK:/Windows/System32/winrm/0409
Worker_10       15332   collecting      2206 (0)        16475 (0)       TSK:/Windows/System32/winevt/TraceFormat
Worker_11       15336   collecting      20089 (0)       3615 (0)        TSK:/Windows/System32/WinBioPlugIns/en-US
Worker_12       15340   collecting      4551 (0)        3547 (0)        TSK:/Windows/System32/wdi/{6
Worker_13       15344   collecting      15735 (0)       12450 (0)       TSK:/Windows/System32/{3DA228B
Worker_14       15348   collecting      11200 (0)       3510 (0)        TSK:/Windows/System32/SMI/Store

Traceback (most recent call last):
File "/data/plaso/plasoenv/bin/log2timeline.py", line 4, in <module>
__import__('pkg_resources').run_script('plaso==1.5.0', 'log2timeline.py')
File "/data/plaso/plasoenv/lib/python2.7/site-packages/pkg_resources/__init__.py", line 744, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/pkg_resources/__init__.py", line 1499, in run_script
exec(code, namespace, namespace)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/EGG-INFO/scripts/log2timeline.py", line 767, in <module>
if not Main():
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/EGG-INFO/scripts/log2timeline.py", line 753, in Main
tool.ProcessSources()
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/EGG-INFO/scripts/log2timeline.py", line 664, in ProcessSources
timezone=self._timezone, yara_rules_string=self._yara_rules_string)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/plaso/frontend/extraction_frontend.py", line 483, in ProcessSources
yara_rules_string=yara_rules_string)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/plaso/multi_processing/task_engine.py", line 791, in ProcessSources
filter_find_specs=filter_find_specs)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/plaso/multi_processing/task_engine.py", line 288, in _ProcessSources
self._ScheduleTasks(storage_writer)
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/plaso/multi_processing/task_engine.py", line 397, in _ScheduleTasks
while event_source or self._task_manager.HasActiveTasks():
File "/data/plaso/plasoenv/lib/python2.7/site-packages/plaso-1.5.0-py2.7.egg/plaso/multi_processing/task_manager.py", line 192, in HasActiveTasks
for task in iter(self._tasks_processing.values()):
File "/usr/lib64/python2.7/collections.py", line 106, in values
return [self[key] for key in self]
KeyError: '7779c7e5f1214e44a6a500dee1d9539d'

# Fixed code
def HasActiveTasks(self):
    """Determines if there are active tasks.

    A task is considered abandoned if its last update exceeds the inactive time.

    Returns:
      bool: True if there are active tasks.
    """
    with self._lock:
        if not self._active_tasks:
            return False

        inactive_time = int(time.time() * 1000000) - self._TASK_INACTIVE_TIME

        for task in iter(self._tasks_processing.values()):
            # Use a local variable to improve performance.
            task_identifier = task.identifier
            if task.last_processing_time < inactive_time:
                del self._tasks_processing[task_identifier]
                self._abandoned_tasks[task_identifier] = task
                del self._active_tasks[task_identifier]

        return bool(self._active_tasks)