Skip to content

fdb.connect() spoils POSIX signal handlers #16

@o3bvv

Description

@o3bvv

Hello again,

I'm trying to investigate an issue with behavior signal handlers during and after invocation of fdb.connect().

I have a handler for SIGINT and SIGTERM which is used for application's graceful shutdown, e.g.:

import signal

def handler(signal_no, stack_frame):
   report_exit_request()
   notify_exit_subscribers()

signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)

The handler works perfectly before the call to fdb.connect(): it captures signals, reports the exit request, notifies subscribers and the main thread waits till all shut down work is finished:

2020-05-26 19:27:06.192580 +0000 [I] [27634 main] app: run… (version='1.0.0')
2020-05-26 19:27:06.193394 +0000 [D] [27634 main] state: loading…
2020-05-26 19:27:06.196915 +0000 [D] [27634 main] state: validating…
2020-05-26 19:27:06.198532 +0000 [D] [27634 main] state: loaded (version='1.0.0')
^C2020-05-26 19:27:07.293636 +0000 [D] [27634 main] exit handler: got exit request
2020-05-26 19:27:16.204282 +0000 [D] [27634 main] state: saving…
2020-05-26 19:27:16.207451 +0000 [D] [27634 main] state: saved
2020-05-26 19:27:16.207780 +0000 [I] [27634 main] app: done

But if fdb.connect() is invoked, the thread is killed immediately after receiving a signal:

2020-05-26 19:30:23.119293 +0000 [I] [27725 main] app: run… (version='1.0.0')
2020-05-26 19:30:23.119877 +0000 [D] [27725 main] state: loading…
2020-05-26 19:30:23.121167 +0000 [D] [27725 main] state: validating…
2020-05-26 19:30:23.122865 +0000 [D] [27725 main] state: loaded (version='1.0.0')
2020-05-26 19:30:23.123084 +0000 [D] [27725 main] db: connecting…
2020-05-26 19:30:23.123252 +0000 [D] [27725 main] db: connection attempt #1…
2020-05-26 19:30:23.264796 +0000 [D] [27725 main] db: connected (firebird_version='2.5.9.27139', ods_version=11.1, sql_dialect=1)
^C2020-05-26 19:30:25.173235 +0000 [D] [27725 main] exit handler: got exit request

As you can see, exit handler was invoked, but the app was killed before finishing (no log messages, as before). It's just a matter of chance that the handler's message managed to propagate to stdout via logger.

If the connection takes too long and the app gets a signal during connection, the thread just bails:

2020-05-26 19:34:07.990052 +0000 [I] [27755 main] app: run… (version='1.0.0')
2020-05-26 19:34:07.990657 +0000 [D] [27755 main] state: loading…
2020-05-26 19:34:07.993211 +0000 [D] [27755 main] state: validating…
2020-05-26 19:34:07.994736 +0000 [D] [27755 main] state: loaded (version='1.0.0')
2020-05-26 19:34:07.994903 +0000 [D] [27755 main] db: connecting…
2020-05-26 19:34:07.995045 +0000 [D] [27755 main] db: connection attempt #1…
^C

I've investigated signal handlers and masks before and after the call to fdb.connect() and they are the same. The rest of the app works as expected.

Noteworthy, setting signal handlers after the call to fdb.connect() once again makes the app to behave as expected. However, this cannot be considered as a workaround, as the app bails during the invocation of fdb.connect().

I've tried to investigate C++ sources of the driver and Python sources of its wrapper, but I couldn't spot any signal management inside them so far.

Could you please provide any suggestions regarding possible root cause?

My OS is macOS 10.15.1 and the driver is provided by FirebirdCS-2.5.9-27139-x86_64.pkg.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions