Use the event loop name instead of thread name for AOS_LOG
This kills 2 birds with 1 stone.
1) A simulated event loop should print out the name of each event
loop, not the program name.
2) prctl(PR_GET_NAME, thread_name_array) can require higher privileges
sometimes, and is un-necesary for simulations. See 1)
Change-Id: I48731b1cabe34ec66a97f27ee720ba3081da4e94
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/aos/logging/context.cc b/aos/logging/context.cc
index b0fd32e..30d275b 100644
--- a/aos/logging/context.cc
+++ b/aos/logging/context.cc
@@ -78,13 +78,23 @@
// Used in aos/linux_code/init.cc when a thread's name is changed.
void ReloadThreadName() {
if (my_context.created()) {
+ my_context->ClearName();
+ }
+}
+
+void Context::ClearName() { name_size = std::numeric_limits<size_t>::max(); }
+
+std::string_view Context::MyName() {
+ if (name_size == std::numeric_limits<size_t>::max()) {
::std::string my_name = GetMyName();
if (my_name.size() + 1 > sizeof(Context::name)) {
Die("logging: process/thread name '%s' is too long\n", my_name.c_str());
}
- strcpy(my_context->name, my_name.c_str());
- my_context->name_size = my_name.size();
+ strcpy(name, my_name.c_str());
+ name_size = my_name.size();
}
+
+ return std::string_view(&name[0], name_size);
}
Context *Context::Get() {
@@ -94,7 +104,7 @@
}
if (__builtin_expect(!my_context.created(), false)) {
my_context.Create();
- ReloadThreadName();
+ my_context->ClearName();
my_context->source = getpid();
}
return my_context.get();
diff --git a/aos/logging/context.h b/aos/logging/context.h
index 25a7233..721b04b 100644
--- a/aos/logging/context.h
+++ b/aos/logging/context.h
@@ -8,6 +8,7 @@
#include <climits>
#include <cstddef>
#include <memory>
+#include <string_view>
#include "aos/logging/sizes.h"
@@ -50,14 +51,19 @@
std::shared_ptr<LogImplementation> implementation;
// A name representing this task/(process and thread).
- char name[LOG_MESSAGE_NAME_LEN];
- size_t name_size;
+ std::string_view MyName();
+ // Clears the cached name so MyName re-checks the thread's actual name.
+ void ClearName();
// What to assign LogMessage::source to in this task/thread.
pid_t source;
// The sequence value to send out with the next message.
uint16_t sequence;
+
+ private:
+ size_t name_size;
+ char name[LOG_MESSAGE_NAME_LEN];
};
} // namespace internal
diff --git a/aos/logging/implementations.cc b/aos/logging/implementations.cc
index 96d00f9..3b4f905 100644
--- a/aos/logging/implementations.cc
+++ b/aos/logging/implementations.cc
@@ -15,15 +15,15 @@
namespace chrono = ::std::chrono;
-void FillInMessageBase(log_level level,
+void FillInMessageBase(log_level level, std::string_view name,
monotonic_clock::time_point monotonic_now,
LogMessage *message) {
Context *context = Context::Get();
message->level = level;
message->source = context->source;
- memcpy(message->name, context->name, context->name_size);
- message->name_length = context->name_size;
+ memcpy(message->name, name.data(), name.size());
+ message->name_length = name.size();
message->seconds =
chrono::duration_cast<chrono::seconds>(monotonic_now.time_since_epoch())
@@ -38,9 +38,10 @@
} // namespace
-void FillInMessage(log_level level, monotonic_clock::time_point monotonic_now,
+void FillInMessage(log_level level, std::string_view name,
+ monotonic_clock::time_point monotonic_now,
const char *format, va_list ap, LogMessage *message) {
- FillInMessageBase(level, monotonic_now, message);
+ FillInMessageBase(level, name, monotonic_now, message);
message->message_length =
ExecuteFormat(message->message, sizeof(message->message), format, ap);
@@ -60,7 +61,8 @@
void HandleMessageLogImplementation::DoLog(log_level level, const char *format,
va_list ap) {
LogMessage message;
- internal::FillInMessage(level, monotonic_now(), format, ap, &message);
+ internal::FillInMessage(level, MyName(), monotonic_now(), format, ap,
+ &message);
HandleMessage(message);
}
diff --git a/aos/logging/implementations.h b/aos/logging/implementations.h
index de1a8dd..36a4411 100644
--- a/aos/logging/implementations.h
+++ b/aos/logging/implementations.h
@@ -13,6 +13,7 @@
#include <functional>
#include <memory>
#include <string>
+#include <string_view>
#include "aos/logging/context.h"
#include "aos/logging/interface.h"
@@ -92,6 +93,12 @@
public:
StreamLogImplementation(FILE *stream);
+ // Returns the name of this actual thread as the name.
+ std::string_view MyName() override {
+ internal::Context *context = internal::Context::Get();
+ return context->MyName();
+ }
+
private:
void HandleMessage(const LogMessage &message) override;
@@ -108,13 +115,18 @@
class CallbackLogImplementation : public HandleMessageLogImplementation {
public:
CallbackLogImplementation(
- const ::std::function<void(const LogMessage &)> &callback)
- : callback_(callback) {}
+ const ::std::function<void(const LogMessage &)> &callback,
+ const std::string *name)
+ : callback_(callback), name_(name) {}
+
+ // Returns the provided name. This is most likely the event loop name.
+ std::string_view MyName() override { return *name_; }
private:
void HandleMessage(const LogMessage &message) override { callback_(message); }
::std::function<void(const LogMessage &)> callback_;
+ const std::string *name_;
};
class ScopedLogRestorer {
@@ -136,18 +148,18 @@
// Fills in *message according to the given inputs (with type kString).
// Used for implementing LogImplementation::DoLog.
-void FillInMessage(log_level level,
+void FillInMessage(log_level level, std::string_view name,
::aos::monotonic_clock::time_point monotonic_now,
const char *format, va_list ap, LogMessage *message)
- __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0)));
+ __attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 4, 0)));
-__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 4, 5))) static inline void
-FillInMessageVarargs(log_level level,
+__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 5, 6))) static inline void
+FillInMessageVarargs(log_level level, std::string_view name,
::aos::monotonic_clock::time_point monotonic_now,
LogMessage *message, const char *format, ...) {
va_list ap;
va_start(ap, format);
- FillInMessage(level, monotonic_now, format, ap, message);
+ FillInMessage(level, name, monotonic_now, format, ap, message);
va_end(ap);
}
diff --git a/aos/logging/implementations_test.cc b/aos/logging/implementations_test.cc
index 1bbfacf..5f98c35 100644
--- a/aos/logging/implementations_test.cc
+++ b/aos/logging/implementations_test.cc
@@ -24,9 +24,15 @@
return ::aos::monotonic_clock::now();
}
+ std::string_view MyName() override {
+ internal::Context *context = internal::Context::Get();
+ return context->MyName();
+ }
+
__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0))) void DoLog(
log_level level, const char *format, va_list ap) override {
- internal::FillInMessage(level, monotonic_now(), format, ap, &message_);
+ internal::FillInMessage(level, MyName(), monotonic_now(), format, ap,
+ &message_);
if (level == FATAL) {
internal::PrintMessage(stderr, message_);
@@ -68,12 +74,13 @@
static_cast<uint32_t>(log_implementation->message().source),
static_cast<uint32_t>(context->source));
}
- if (log_implementation->message().name_length != context->name_size ||
- memcmp(log_implementation->message().name, context->name,
- context->name_size) != 0) {
+ if (log_implementation->message().name_length != context->MyName().size() ||
+ memcmp(log_implementation->message().name, context->MyName().data(),
+ context->MyName().size()) != 0) {
AOS_LOG(FATAL, "got a message from %.*s, but we're %s\n",
static_cast<int>(log_implementation->message().name_length),
- log_implementation->message().name, context->name);
+ log_implementation->message().name,
+ std::string(context->MyName()).c_str());
}
if (strstr(log_implementation->message().message, message.c_str()) ==
NULL) {
@@ -221,11 +228,12 @@
SetImplementation(std::make_shared<StreamLogImplementation>(stdout));
LogImplementation *curr_impl = GetImplementation().get();
+ std::string name = "name";
{
ScopedLogRestorer log_restorer;
- log_restorer.Swap(
- std::make_shared<CallbackLogImplementation>([](const LogMessage &) {}));
+ log_restorer.Swap(std::make_shared<CallbackLogImplementation>(
+ [](const LogMessage &) {}, &name));
ASSERT_NE(curr_impl, GetImplementation().get());
}
diff --git a/aos/logging/interface.cc b/aos/logging/interface.cc
index 39492ad..336dbc0 100644
--- a/aos/logging/interface.cc
+++ b/aos/logging/interface.cc
@@ -49,8 +49,9 @@
implementation->DoLog(level, format, ap1);
} else {
aos::logging::LogMessage message;
- aos::logging::internal::FillInMessage(level, aos::monotonic_clock::now(),
- format, ap, &message);
+ aos::logging::internal::FillInMessage(level, context->MyName(),
+ aos::monotonic_clock::now(), format,
+ ap, &message);
aos::logging::internal::PrintMessage(stderr, message);
}
va_end(ap1);
diff --git a/aos/logging/interface.h b/aos/logging/interface.h
index f6fa249..d2663e7 100644
--- a/aos/logging/interface.h
+++ b/aos/logging/interface.h
@@ -4,6 +4,7 @@
#include <cstdarg>
#include <functional>
#include <string>
+#include <string_view>
#include "aos/logging/logging.h"
#include "aos/macros.h"
@@ -29,6 +30,10 @@
virtual ~LogImplementation() {}
+ // Returns the identifying name to be used when logging. This could be the
+ // event loop name or the thread name.
+ virtual std::string_view MyName() = 0;
+
// Actually logs the given message. Implementations should somehow create a
// LogMessage and then call internal::FillInMessage.
__attribute__((format(GOOD_PRINTF_FORMAT_TYPE, 3, 0))) virtual void DoLog(