# Buggy code
def on_shutdown(
    manager: TaskManager.TaskManager, unsaved_jobs_lock: Lock
) -> Callable[[signal.Signals, Any], None]:
    def actual_callback(s: signal.Signals, __: Any) -> None:
        global shutting_down
        manager.logger.error("Got interupted by %r, shutting down", s)
        with unsaved_jobs_lock:
            shutting_down = True
        manager.close(relaxed=False)
        sys.exit(1)

    return actual_callback


# Traceback (AttributeError)
browser_manager      - INFO     - BROWSER 4: Launching browser...
task_manager         - INFO     -

OpenWPM Version: b'v0.13.0-3-g051a384'
Firefox Version: b'83.0'

========== Manager Configuration ==========
{
"aggregator_address": [
"127.0.0.1",
51454
],
"data_directory": "/Users/ankushdua/Desktop/",
"database_name": "/Users/ankushdua/Desktop/crawl-data.sqlite",
"failure_limit": null,
"log_directory": "/Users/ankushdua/Desktop/",
"log_file": "/Users/ankushdua/Desktop/openwpm.log",
"logger_address": [
"127.0.0.1",
51453
],
"memory_watchdog": true,
"num_browsers": 1,
"output_format": "local",
"process_watchdog": true,
"s3_bucket": null,
"s3_directory": null,
"screenshot_path": "/Users/ankushdua/Desktop/screenshots",
"source_dump_path": "/Users/ankushdua/Desktop/sources",
"testing": false
}

========== Browser Configuration ==========
Keys:
{
"browser_id": 0,
"bot_mitigation": 1,
"browser": 2,
"callstack_instrument": 3,
"cookie_instrument": 4,
"display_mode": 5,
"dns_instrument": 6,
"donottrack": 7,
"extension_enabled": 8,
"http_instrument": 9,
"js_instrument": 10,
"navigation_instrument": 11,
"prefs": 12,
"recovery_tar": 13,
"save_content": 14,
"tp_cookies": 15,
"tracking-protection": 16
}

0  1      2        3     4     5         6     7      8     9     10    11    12    13    14     15      16
---  -----  -------  ----  ----  --------  ----  -----  ----  ----  ----  ----  ----  ----  -----  ------  -----
4  False  firefox  True  True  headless  True  False  True  True  True  True  {}          False  always  False

========== JS Instrument Settings ==========
{
"4": "[{\"object\": window['ScriptProcessorNode'].prototype, \"instrumentedName\": \"ScriptProcessorNode\", \"logSettings\": {\"propertiesToInstrument\": [], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window['GainNode'].prototype, \"instrumentedName\": \"GainNode\", \"logSettings\": {\"propertiesToInstrument\": [], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window['AnalyserNode'].prototype, \"instrumentedName\": \"AnalyserNode\", \"logSettings\": {\"propertiesToInstrument\": [], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window['OscillatorNode'].prototype, \"instrumentedName\": \"OscillatorNode\", \"logSettings\": {\"propertiesToInstrument\": [], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window['OfflineAudioContext'].prototype, \"instrumentedName\": \"OfflineAudioContext\", \"logSettings\": {\"propertiesToInstrument\": [], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window['AudioContext'].prototype, \"instrumentedName\": \"AudioContext\", \"logSettings\": {\"propertiesToInstrument\": [], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window['RTCPeerConnection'].prototype, \"instrumentedName\": \"RTCPeerConnection\", \"logSettings\": {\"propertiesToInstrument\": [], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window['HTMLCanvasElement'].prototype, \"instrumentedName\": \"HTMLCanvasElement\", \"logSettings\": {\"propertiesToInstrument\": [], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window['Storage'].prototype, \"instrumentedName\": \"Storage\", \"logSettings\": {\"propertiesToInstrument\": [], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window.navigator, \"instrumentedName\": \"window.navigator\", \"logSettings\": {\"propertiesToInstrument\": [], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window['CanvasRenderingContext2D'].prototype, \"instrumentedName\": \"CanvasRenderingContext2D\", \"logSettings\": {\"propertiesToInstrument\": [], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [\"beginPath\", \"closePath\", \"quadraticCurveTo\", \"drawImage\", \"translate\", \"lineTo\", \"transform\", \"setTransform\", \"clearRect\", \"globalAlpha\", \"canvas\", \"moveTo\"], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window, \"instrumentedName\": \"window\", \"logSettings\": {\"propertiesToInstrument\": [\"sessionStorage\", \"name\", \"localStorage\"], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window.document, \"instrumentedName\": \"window.document\", \"logSettings\": {\"propertiesToInstrument\": [\"referrer\", \"cookie\"], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": true, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}, {\"object\": window.screen, \"instrumentedName\": \"window.screen\", \"logSettings\": {\"propertiesToInstrument\": [\"colorDepth\", \"pixelDepth\"], \"nonExistingPropertiesToInstrument\": [], \"excludedProperties\": [], \"logCallStack\": false, \"logFunctionsAsStrings\": false, \"logFunctionGets\": false, \"preventSets\": false, \"recursive\": false, \"depth\": 5}}]"
}

========== Input profile tar files ==========
No profile tar files specified

========== Output (archive) profile dirs ==========
No profile archive directories specified


task_manager         - INFO     - Starting to work on CommandSequence with visit_id 6 on browser with id 4
Traceback (most recent call last):
File "demo.py", line 48, in <module>
command_sequence = command_sequence.CommandSequence(
AttributeError: 'CommandSequence' object has no attribute 'CommandSequence'
browser_manager      - INFO     - BROWSER 4: EXECUTING COMMAND: IntitializeCommand()
browser_manager      - INFO     - BROWSER 4: EXECUTING COMMAND: GetCommand(http://www.example.com,3)
browser_manager      - INFO     - BROWSER 4: EXECUTING COMMAND: FinalizeCommand(5)
task_manager         - INFO     - Finished working on CommandSequence with visit_id 6 on browser with id 4
Exception in thread OpenWPM-watchdog:
Traceback (most recent call last):
File "/Users/ankushdua/anaconda3/envs/openwpm1/lib/python3.8/site-packages/psutil/_psosx.py", line 342, in wrapper
return fun(self, *args, **kwargs)
File "/Users/ankushdua/anaconda3/envs/openwpm1/lib/python3.8/site-packages/psutil/_psosx.py", line 484, in memory_full_info
uss = cext.proc_memory_uss(self.pid)
PermissionError: [Errno 13] Access denied (originated from task_for_pid)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/Users/ankushdua/anaconda3/envs/openwpm1/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/Users/ankushdua/anaconda3/envs/openwpm1/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/Users/ankushdua/OpenWPM/openwpm/task_manager.py", line 231, in _manager_watchdog
mem_bytes += child.memory_full_info().uss
File "/Users/ankushdua/anaconda3/envs/openwpm1/lib/python3.8/site-packages/psutil/__init__.py", line 1072, in memory_full_info
return self._proc.memory_full_info()
File "/Users/ankushdua/anaconda3/envs/openwpm1/lib/python3.8/site-packages/psutil/_psosx.py", line 349, in wrapper
raise AccessDenied(self.pid, self._name)
psutil.AccessDenied: psutil.AccessDenied (pid=89532)
CommandSequence http://www.example.com done
browser_manager      - INFO     - BROWSER 4: BrowserManager restart initiated. Clear profile? True
browser_manager      - INFO     - BROWSER 4: Launching browser...

# Fixed code
def on_shutdown(
    manager: TaskManager, unsaved_jobs_lock: Lock
) -> Callable[[signal.Signals, Any], None]:
    def actual_callback(s: signal.Signals, __: Any) -> None:
        global shutting_down
        manager.logger.error("Got interupted by %r, shutting down", s)
        with unsaved_jobs_lock:
            shutting_down = True
        manager.close(relaxed=False)
        sys.exit(1)

    return actual_callback