|
16 | 16 | import inspect |
17 | 17 | import subprocess |
18 | 18 | import logging |
| 19 | +import traceback |
| 20 | +from signal import SIGKILL |
19 | 21 |
|
20 | 22 |
|
21 | 23 | # TODO: provide alternative when multiprocessing is not available |
@@ -324,21 +326,34 @@ def memory_usage(proc=-1, interval=.1, timeout=None, timestamps=False, |
324 | 326 | raise ValueError |
325 | 327 |
|
326 | 328 | while True: |
| 329 | + exit_block = False |
327 | 330 | child_conn, parent_conn = Pipe() # this will store MemTimer's results |
328 | 331 | p = MemTimer(os.getpid(), interval, child_conn, backend, |
329 | 332 | timestamps=timestamps, |
330 | 333 | max_usage=max_usage, |
331 | 334 | include_children=include_children) |
332 | 335 | p.start() |
333 | 336 | parent_conn.recv() # wait until we start getting memory |
334 | | - returned = f(*args, **kw) |
335 | | - parent_conn.send(0) # finish timing |
336 | | - ret = parent_conn.recv() |
337 | | - n_measurements = parent_conn.recv() |
338 | | - if retval: |
339 | | - ret = ret, returned |
| 337 | + |
| 338 | + # When there is an exception in the "proc" - the (spawned) monitoring processes don't get killed. |
| 339 | + # Therefore, the whole process hangs indefinitely. Here, we are ensuring that the process gets killed! |
| 340 | + try: |
| 341 | + returned = f(*args, **kw) |
| 342 | + parent_conn.send(0) # finish timing |
| 343 | + ret = parent_conn.recv() |
| 344 | + n_measurements = parent_conn.recv() |
| 345 | + if retval: |
| 346 | + ret = ret, returned |
| 347 | + except Exception: |
| 348 | + if has_psutil: |
| 349 | + parent = psutil.Process(os.getpid()) |
| 350 | + for child in parent.children(recursive=True): |
| 351 | + os.kill(child.pid, SIGKILL) |
| 352 | + p.join(0) |
| 353 | + raise |
| 354 | + |
340 | 355 | p.join(5 * interval) |
341 | | - if n_measurements > 4 or interval < 1e-6: |
| 356 | + if exit_block or n_measurements > 4 or interval < 1e-6: |
342 | 357 | break |
343 | 358 | interval /= 10. |
344 | 359 | elif isinstance(proc, subprocess.Popen): |
@@ -1108,7 +1123,7 @@ def exec_with_profiler(filename, profiler, backend): |
1108 | 1123 | execfile(filename, ns, ns) |
1109 | 1124 | else: |
1110 | 1125 | def exec_with_profiler(filename, profiler, backend): |
1111 | | - choose_backend(backend) |
| 1126 | + _backend = choose_backend(backend) |
1112 | 1127 | if _backend == 'tracemalloc' and has_tracemalloc: |
1113 | 1128 | tracemalloc.start() |
1114 | 1129 | builtins.__dict__['profile'] = profiler |
|
0 commit comments