Signal forwarding traceback #368

Closed
opened 2020-11-18 05:08:22 +00:00 by witten · 2 comments
Owner

Reported by f0x.

What I'm trying to do and why

Send a signal to borgmatic and have it be forwarded on to Borg. (In this case, SIGUSR1 for instrumentation purposes. But applies to other signals too.)

Steps to reproduce (if a bug)

Start a borgmatic create such that it invokes Borg. While Borg is running:

kill -SIGUSR1 [pid of borgmatic]

Actual behavior (if a bug)

Traceback (most recent call last):
  File "/usr/bin/borgmatic", line 33, in <module>
    sys.exit(load_entry_point('borgmatic==1.5.10', 'console_scripts', 'borgmatic')())
  File "/usr/lib/python3.8/site-packages/borgmatic/commands/borgmatic.py", line 785, in main
    summary_logs = parse_logs + list(collect_configuration_run_summary_logs(configs, arguments))
  File "/usr/lib/python3.8/site-packages/borgmatic/commands/borgmatic.py", line 683, in collect_configuration_run_summary_logs
    results = list(run_configuration(config_filename, config, arguments))
  File "/usr/lib/python3.8/site-packages/borgmatic/commands/borgmatic.py", line 124, in run_configuration
    yield from run_actions(
  File "/usr/lib/python3.8/site-packages/borgmatic/commands/borgmatic.py", line 317, in run_actions
    json_output = borg_create.create_archive(
  File "/usr/lib/python3.8/site-packages/borgmatic/borg/create.py", line 281, in create_archive
    return execute_command(full_command, output_log_level, output_file, borg_local_path=local_path)
  File "/usr/lib/python3.8/site-packages/borgmatic/execute.py", line 198, in execute_command
    log_outputs(
  File "/usr/lib/python3.8/site-packages/borgmatic/execute.py", line 71, in log_outputs
    (ready_buffers, _, _) = select.select(output_buffers, [], [])
  File "/usr/lib/python3.8/site-packages/borgmatic/signals.py", line 9, in _handle_signal
    os.killpg(os.getpgrp(), signal_number)
  File "/usr/lib/python3.8/site-packages/borgmatic/signals.py", line 9, in _handle_signal
    os.killpg(os.getpgrp(), signal_number)
  File "/usr/lib/python3.8/site-packages/borgmatic/signals.py", line 9, in _handle_signal
    os.killpg(os.getpgrp(), signal_number)
  [Previous line repeated 986 more times]
RecursionError: maximum recursion depth exceeded while calling a Python object 

Expected behavior (if a bug)

No traceback, and borgmatic forwards the signal onto Borg.

Other notes / implementation ideas

The problem here is that borgmatic's existing signal handler forwards the signal to borgmatic's entire process group, which include child processes like Borg. And while that means Borg receives the forwarded signal as designed, it also means borgmatic re-receives its own forwarded signal (being in the same process group).

Then the signal gets handled again, gets forwarded again, repeat ad infinitum.

Boom, stack blown.

Environment

borgmatic version: 1.5.10, master (1.5.11.dev0)

borgmatic installation method: pip install --editable

Borg version: 1.1.14

Python version: 3.8.6

Database version (if applicable): N/A

operating system and version: Manjaro stable

Reported by f0x. #### What I'm trying to do and why Send a signal to borgmatic and have it be forwarded on to Borg. (In this case, SIGUSR1 for instrumentation purposes. But applies to other signals too.) #### Steps to reproduce (if a bug) Start a `borgmatic create` such that it invokes Borg. While Borg is running: ```bash kill -SIGUSR1 [pid of borgmatic] ``` #### Actual behavior (if a bug) ```python Traceback (most recent call last): File "/usr/bin/borgmatic", line 33, in <module> sys.exit(load_entry_point('borgmatic==1.5.10', 'console_scripts', 'borgmatic')()) File "/usr/lib/python3.8/site-packages/borgmatic/commands/borgmatic.py", line 785, in main summary_logs = parse_logs + list(collect_configuration_run_summary_logs(configs, arguments)) File "/usr/lib/python3.8/site-packages/borgmatic/commands/borgmatic.py", line 683, in collect_configuration_run_summary_logs results = list(run_configuration(config_filename, config, arguments)) File "/usr/lib/python3.8/site-packages/borgmatic/commands/borgmatic.py", line 124, in run_configuration yield from run_actions( File "/usr/lib/python3.8/site-packages/borgmatic/commands/borgmatic.py", line 317, in run_actions json_output = borg_create.create_archive( File "/usr/lib/python3.8/site-packages/borgmatic/borg/create.py", line 281, in create_archive return execute_command(full_command, output_log_level, output_file, borg_local_path=local_path) File "/usr/lib/python3.8/site-packages/borgmatic/execute.py", line 198, in execute_command log_outputs( File "/usr/lib/python3.8/site-packages/borgmatic/execute.py", line 71, in log_outputs (ready_buffers, _, _) = select.select(output_buffers, [], []) File "/usr/lib/python3.8/site-packages/borgmatic/signals.py", line 9, in _handle_signal os.killpg(os.getpgrp(), signal_number) File "/usr/lib/python3.8/site-packages/borgmatic/signals.py", line 9, in _handle_signal os.killpg(os.getpgrp(), signal_number) File "/usr/lib/python3.8/site-packages/borgmatic/signals.py", line 9, in _handle_signal os.killpg(os.getpgrp(), signal_number) [Previous line repeated 986 more times] RecursionError: maximum recursion depth exceeded while calling a Python object ``` #### Expected behavior (if a bug) No traceback, and borgmatic forwards the signal onto Borg. #### Other notes / implementation ideas The problem here is that borgmatic's existing signal handler forwards the signal to borgmatic's entire process group, which include child processes like Borg. And while that means Borg receives the forwarded signal as designed, it also means borgmatic re-receives its own forwarded signal (being in the same process group). Then the signal gets handled again, gets forwarded again, repeat ad infinitum. Boom, stack blown. #### Environment **borgmatic version:** 1.5.10, master (1.5.11.dev0) **borgmatic installation method:** `pip install --editable` **Borg version:** 1.1.14 **Python version:** 3.8.6 **Database version (if applicable):** N/A **operating system and version:** Manjaro stable
Author
Owner

Fixed in master by stopping the infinite recursion when detected. This fix will be part of the next release.

Fixed in master by stopping the infinite recursion when detected. This fix will be part of the next release.
witten added the
bug
label 2020-11-18 18:32:10 +00:00
Author
Owner

Just released in borgmatic 1.5.11!

Just released in borgmatic 1.5.11!
Sign in to join this conversation.
No Milestone
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: borgmatic-collective/borgmatic#368
No description provided.