3

I'm using a python script to perform asynchronous Nmap scans with the python-nmap v0.6.1 library and Python v3.8.3. When I follow the simple asynchronous example displayed on the page, the scan completes successfully but prints the following "Exception ignored" message.

Exception ignored in: <function PortScannerAsync.__del__ at 0x000001B88EE40430>
Traceback (most recent call last):
  File "C:\Users\username\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\nmap\nmap.py", line 741, in __del__
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.1008.0_x64__qbz5n2kfra8p0\lib\multiprocessing\process.py", line 133, in terminate
AttributeError: 'NoneType' object has no attribute 'terminate'

I looked into the PortScannerAsync object's __del__ method (line 741 in the library file) and found that two checks were being performed before calling terminate. Here is the snippet in question:

def __del__(self):
    """
    Cleanup when deleted

    """
    if self._process is not None:
        try:
            if self._process.is_alive():
                self._process.terminate() #this is line 741
        except AssertionError:
            # Happens on python3.4
            # when using PortScannerAsync twice in a row
            pass

    self._process = None
    return

So the library should be confirming:

(1) self._process is not None

(2) self._process_is_alive() returns true before calling terminate.

To make sure nothing weird was happening with the object in question, I added the following print lines to run right before the terminate method (line 741):

print(type(self._process)) print(dir(self._process))

The Exception is still printed even though the print methods I added confirms that:

(1) it is a multiprocessing Process object: (<class 'multiprocessing.context.Process'>) and

(2) it has a terminate method: (['_Popen', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_args', '_bootstrap', '_check_closed', '_closed', '_config', '_identity', '_kwargs', '_name', '_parent_name', '_parent_pid', '_popen', '_start_method', '_target', 'authkey', 'close', 'daemon', 'exitcode', 'ident', 'is_alive', 'join', 'kill', 'name', 'pid', 'run', 'sentinel', 'start', 'terminate'])

--

Am I missing something obvious? I am new to multiprocessing in python so I am not sure if I am lacking any required components.

Here is the full script:

import nmap
nma = nmap.PortScannerAsync()

def callback_result(host, scan_result):
    print('---')
    print(host, scan_result)

if __name__ == '__main__':
    nma.scan(hosts='10.0.0.69', arguments='-sn', callback=callback_result)
    while nma.still_scanning():
        print('waiting....')
        nma.wait(2)
Adam
  • 43
  • 6
  • `multiprocessing.Process.terminate()` internally calls `self._popen.terminate()`; I suspect that's the reference that is actually failing. Either the Process has never been started (leaving `_popen` at its default value of `None`), or that attribute has already been cleaned up when `__del__` gets run. – jasonharper Jul 05 '20 at 18:40
  • Hi Jason, thanks for the response! Considering that the print lines I added were only run once, I think the main process only created a single additional process. Therefore, your latter suggestion is more likely. I'll look into the logic of multiprocessing.py file and see what's going on there. – Adam Jul 05 '20 at 21:36

0 Answers0