fix(px4_daemon): fix startup stdout TLS race

Create the server thread-local stdout key before marking the daemon as
running, preventing early startup logs from using an invalid FILE pointer.
This commit is contained in:
Eric Katzfey
2026-07-21 09:26:30 -07:00
committed by Eric Katzfey
parent 00f436698b
commit cbe8680a66
3 changed files with 27 additions and 10 deletions

View File

@@ -66,17 +66,34 @@ Server::Server(int instance_id)
: _mutex(PTHREAD_MUTEX_INITIALIZER),
_instance_id(instance_id)
{
int ret = pthread_key_create(&_key, _pthread_key_destructor);
if (ret != 0) {
PX4_ERR("failed to create pthread key");
} else {
_key_valid = true;
}
_instance = this;
}
Server::~Server()
{
_instance = nullptr;
if (_key_valid) {
pthread_key_delete(_key);
}
}
int
Server::start()
{
if (!_key_valid) {
return -1;
}
std::string sock_path = get_socket_path(_instance_id);
// Delete socket in case it exists already.
@@ -129,13 +146,6 @@ void Server::_pthread_key_destructor(void *arg)
void
Server::_server_main()
{
int ret = pthread_key_create(&_key, _pthread_key_destructor);
if (ret != 0) {
PX4_ERR("failed to create pthread key");
return;
}
// The list of file descriptors to watch.
std::vector<pollfd> poll_fds;
@@ -182,7 +192,7 @@ Server::_server_main()
// Start a new thread to handle the client.
pthread_t *thread = &_fd_to_thread[client];
ret = pthread_create(thread, nullptr, Server::_handle_client, thread_stdout);
int ret = pthread_create(thread, nullptr, Server::_handle_client, thread_stdout);
if (ret != 0) {
PX4_ERR("could not start pthread (%i)", ret);

View File

@@ -89,6 +89,12 @@ public:
{
return _instance->_key;
}
static bool has_pthread_key()
{
return _instance != nullptr && _instance->_key_valid;
}
private:
static void *_server_main_trampoline(void *arg);
void _server_main();
@@ -111,7 +117,8 @@ private:
std::map<int, pthread_t> _fd_to_thread;
pthread_mutex_t _mutex; ///< Protects _fd_to_thread.
pthread_key_t _key;
pthread_key_t _key{};
bool _key_valid{false};
int _instance_id; ///< instance ID for running multiple instances of the px4 server

View File

@@ -61,7 +61,7 @@ using namespace px4_daemon;
FILE *get_stdout(bool *isatty_)
{
// If the server is not running, we are not in a thread that has been started
if (!Server::is_running()) {
if (!Server::is_running() || !Server::has_pthread_key()) {
if (isatty_) { *isatty_ = isatty(1); }
return stdout;