mirror of
https://github.com/Zygo/bees.git
synced 2025-05-17 21:35:45 +02:00
BeesNote: thread naming fixes
Move pthread_setname_np to the same place we do pthread_getname_np. Detect errors in pthread_getname_np--but don't throw an exception because we would call ourself recursively from the exception handler when it tries to log the exception. Fix the order of set_name and the first BEESNOTE/BEESLOG call in threads, closing small time intervals where logs have the wrong thread name, and that wrong name becomes persistent for the thread. Make the main thread's name "bees" because Linux kernel stack traces use the pthread name of the main thread instead of the name of the process. Anonymous threads get the process name (usually "bees"). We should not have any such threads, but we do. This appears to occur mostly during exception stack unwinding. GCC/pthread bug? Fixes: https://github.com/Zygo/bees/issues/51 Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
parent
c17618c371
commit
0710208354
16
lib/task.cc
16
lib/task.cc
@ -85,11 +85,25 @@ namespace crucible {
|
|||||||
TaskState::exec()
|
TaskState::exec()
|
||||||
{
|
{
|
||||||
THROW_CHECK0(invalid_argument, m_exec_fn);
|
THROW_CHECK0(invalid_argument, m_exec_fn);
|
||||||
|
THROW_CHECK0(invalid_argument, m_print_fn);
|
||||||
|
|
||||||
|
char buf[24];
|
||||||
|
memset(buf, '\0', sizeof(buf));
|
||||||
|
DIE_IF_MINUS_ERRNO(pthread_getname_np(pthread_self(), buf, sizeof(buf)));
|
||||||
|
Cleanup pthread_name_cleaner([&]() {
|
||||||
|
pthread_setname_np(pthread_self(), buf);
|
||||||
|
});
|
||||||
|
ostringstream oss;
|
||||||
|
m_print_fn(oss);
|
||||||
|
auto thread_name = oss.str();
|
||||||
|
DIE_IF_MINUS_ERRNO(pthread_setname_np(pthread_self(), thread_name.c_str()));
|
||||||
|
|
||||||
weak_ptr<TaskState> this_task_wp = shared_from_this();
|
weak_ptr<TaskState> this_task_wp = shared_from_this();
|
||||||
Cleanup cleaner([&]() {
|
Cleanup current_task_cleaner([&]() {
|
||||||
swap(this_task_wp, tl_current_task_wp);
|
swap(this_task_wp, tl_current_task_wp);
|
||||||
});
|
});
|
||||||
swap(this_task_wp, tl_current_task_wp);
|
swap(this_task_wp, tl_current_task_wp);
|
||||||
|
|
||||||
m_exec_fn();
|
m_exec_fn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,13 +15,10 @@ BeesThread::exec(function<void()> func)
|
|||||||
m_timer.reset();
|
m_timer.reset();
|
||||||
BEESLOGDEBUG("BeesThread exec " << m_name);
|
BEESLOGDEBUG("BeesThread exec " << m_name);
|
||||||
m_thread_ptr = make_shared<thread>([=]() {
|
m_thread_ptr = make_shared<thread>([=]() {
|
||||||
BEESLOGDEBUG("Starting thread " << m_name);
|
|
||||||
BeesNote::set_name(m_name);
|
BeesNote::set_name(m_name);
|
||||||
|
BEESLOGDEBUG("Starting thread " << m_name);
|
||||||
BEESNOTE("thread function");
|
BEESNOTE("thread function");
|
||||||
Timer thread_time;
|
Timer thread_time;
|
||||||
catch_all([&]() {
|
|
||||||
DIE_IF_MINUS_ERRNO(pthread_setname_np(pthread_self(), m_name.c_str()));
|
|
||||||
});
|
|
||||||
catch_all([&]() {
|
catch_all([&]() {
|
||||||
func();
|
func();
|
||||||
});
|
});
|
||||||
|
42
src/bees.cc
42
src/bees.cc
@ -132,11 +132,15 @@ void
|
|||||||
BeesNote::set_name(const string &name)
|
BeesNote::set_name(const string &name)
|
||||||
{
|
{
|
||||||
tl_name = name;
|
tl_name = name;
|
||||||
|
catch_all([&]() {
|
||||||
|
DIE_IF_MINUS_ERRNO(pthread_setname_np(pthread_self(), name.c_str()));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
BeesNote::get_name()
|
BeesNote::get_name()
|
||||||
{
|
{
|
||||||
|
// Use explicit name if given
|
||||||
if (!tl_name.empty()) {
|
if (!tl_name.empty()) {
|
||||||
return tl_name;
|
return tl_name;
|
||||||
}
|
}
|
||||||
@ -145,26 +149,27 @@ BeesNote::get_name()
|
|||||||
// remember it. Each output message may be a different Task.
|
// remember it. Each output message may be a different Task.
|
||||||
// The current task is thread_local so we don't need to worry
|
// The current task is thread_local so we don't need to worry
|
||||||
// about it being destroyed under us.
|
// about it being destroyed under us.
|
||||||
auto current_task = Task::current_task();
|
auto current_task = Task::current_task();
|
||||||
if (current_task) {
|
if (current_task) {
|
||||||
ostringstream oss;
|
ostringstream oss;
|
||||||
oss << current_task;
|
oss << current_task;
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// OK try the pthread name next.
|
// OK try the pthread name next.
|
||||||
char buf[100];
|
char buf[24];
|
||||||
memset(buf, '\0', sizeof(buf));
|
memset(buf, '\0', sizeof(buf));
|
||||||
pthread_getname_np(pthread_self(), buf, sizeof(buf));
|
int err = pthread_getname_np(pthread_self(), buf, sizeof(buf));
|
||||||
buf[sizeof(buf) - 1] = '\0';
|
if (err) {
|
||||||
tl_name = buf;
|
return string("pthread_getname_np: ") + strerror(err);
|
||||||
|
|
||||||
// Give up and use a generic name.
|
|
||||||
if (tl_name.empty()) {
|
|
||||||
tl_name = "bees";
|
|
||||||
}
|
}
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
|
||||||
return tl_name;
|
// thread_getname_np returns process name
|
||||||
|
// ...by default? ...for the main thread?
|
||||||
|
// ...except during exception handling?
|
||||||
|
// ...randomly?
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
BeesNote::ThreadStatusMap
|
BeesNote::ThreadStatusMap
|
||||||
@ -629,8 +634,11 @@ bees_main(int argc, char *argv[])
|
|||||||
BEESCOUNT(exception_caught);
|
BEESCOUNT(exception_caught);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The thread name for the main function is also what the kernel
|
||||||
|
// Oops messages call the entire process. So even though this
|
||||||
|
// thread's proper title is "main", let's call it "bees".
|
||||||
|
BeesNote::set_name("bees");
|
||||||
BEESNOTE("main");
|
BEESNOTE("main");
|
||||||
BeesNote::set_name("main");
|
|
||||||
|
|
||||||
list<shared_ptr<BeesContext>> all_contexts;
|
list<shared_ptr<BeesContext>> all_contexts;
|
||||||
shared_ptr<BeesContext> bc;
|
shared_ptr<BeesContext> bc;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user