blacklanternsecurity / bbot

A recursive internet scanner for hackers.
https://www.blacklanternsecurity.com/bbot/
GNU General Public License v3.0
4.03k stars 370 forks source link

RuntimeError: context has already been set #1385

Open colin-stubbs opened 1 month ago

colin-stubbs commented 1 month ago

Describe the bug

When running tests confusing errors are produced due to an exception raised by the testing process, whereby bbot Scanner objects are reused and on subsequent usage python multiprocessing method 'spawn' is attempted again, when it has already been set to 'spawn'.

This may also occur in other situations where Scanner objects are created and reused for valid reasons.

bbot  | TRACE    bbot.scanner:scanner.py:948 Traceback (most recent call last):
bbot  |   File "/usr/src/bbot/bbot/scanner/scanner.py", line 261, in __init__
bbot  |     mp.set_start_method("spawn")
bbot  |   File "/usr/local/lib/python3.10/multiprocessing/context.py", line 247, in set_start_method
bbot  |     raise RuntimeError('context has already been set')
bbot  | RuntimeError: context has already been set
bbot  | 

This is due to this code inside __init__() for the Scanner class from ./bbot/scanner/scanner.py

        # multiprocessing thread pool
        try:
            mp.set_start_method("spawn")
        except Exception:
            self.warning(f"Failed to set multiprocessing spawn method. This may negatively affect performance.")

This appears to be trivially resolved by adding an if statement based on the return value of mp.get_start_method(),

e.g.

        # multiprocessing thread pool
        try:
            if mp.get_start_method() != "spawn":
                mp.set_start_method("spawn")
        except Exception:
            self.warning(f"Failed to set multiprocessing spawn method. This may negatively affect performance.")

No more errors.

Expected behavior

No errors, no exceptions.

BBOT Command

./bbot/test/run_tests.sh

OS, BBOT Installation Method + Version

Not relevant, using latest code from git main branch.

BBOT Config

Not relevant, using latest code from git main branch.

Logs

bbot  | TRACE    bbot.scanner:scanner.py:948 Traceback (most recent call last):
bbot  |   File "/usr/src/bbot/bbot/scanner/scanner.py", line 261, in __init__
bbot  |     mp.set_start_method("spawn")
bbot  |   File "/usr/local/lib/python3.10/multiprocessing/context.py", line 247, in set_start_method
bbot  |     raise RuntimeError('context has already been set')
bbot  | RuntimeError: context has already been set
bbot  | 

Screenshots

Not relevant.

TheTechromancer commented 1 month ago

Thanks for noticing this. Would you care to make a quick PR?

colin-stubbs commented 1 month ago

Shall do, I've already started testing it... though it seems my assumed solution may not actually work, I'm not sure why as yet. Possibly python versioning.

I've got a few other things that I'll wind up logging as bugs too, before logging some feature requests with corresponding PR's for the modules I've been building.

As feedback... the bbot doco is generally great! Fantastic even. The hardest part for someone new to the code base is actually understanding the testing process, e.g. how to write test modules and how the various pytest driven bits'n'bobs all hang together.

This whole multiprocessing spawn thing was a non-event side track from trying to understand why aspects to testing were failing :-(

Some sort of guide to "Module Testing" in the developer docs would be great to be able to refer to.

TheTechromancer commented 1 month ago

This is good feedback for the developer docs; you might be one of the first to read it so I'm glad you're noticing this stuff. Excited to see what modules you're working on!

TheTechromancer commented 1 month ago

though it seems my assumed solution may not actually work

Ah and I think the reason is because we automatically log tracebacks for warnings and errors:

Screenshot_20240517-082431.png

So passing trace=False to the logging call should do the trick.