Merge "Move default tag from libbase to liblog"

am: b40c15e101

Change-Id: I3df5ce6a45cd4ee8cdd912d305a1e06bfedc4548
This commit is contained in:
Tom Cherry 2020-01-23 13:14:56 -08:00 committed by android-build-merger
commit 44c7bcb29e
10 changed files with 183 additions and 48 deletions

View file

@ -115,7 +115,6 @@ void StdioLogger(LogId, LogSeverity, const char*, const char*, unsigned int, con
void DefaultAborter(const char* abort_message);
std::string GetDefaultTag();
void SetDefaultTag(const std::string& tag);
// We expose this even though it is the default because a user that wants to

View file

@ -50,6 +50,7 @@ const std::optional<LibLogFunctions>& GetLibLogFunctions() {
DLSYM(__android_log_default_aborter)
DLSYM(__android_log_set_minimum_priority);
DLSYM(__android_log_get_minimum_priority);
DLSYM(__android_log_set_default_tag);
#undef DLSYM
return real_liblog_functions;
@ -72,6 +73,7 @@ const std::optional<LibLogFunctions>& GetLibLogFunctions() {
.__android_log_default_aborter = __android_log_default_aborter,
.__android_log_set_minimum_priority = __android_log_set_minimum_priority,
.__android_log_get_minimum_priority = __android_log_get_minimum_priority,
.__android_log_set_default_tag = __android_log_set_default_tag,
};
}();
return liblog_functions;

View file

@ -38,6 +38,7 @@ struct LibLogFunctions {
void (*__android_log_default_aborter)(const char* abort_message);
int (*__android_log_set_minimum_priority)(int priority);
int (*__android_log_get_minimum_priority)();
void (*__android_log_set_default_tag)(const char* tag);
};
const std::optional<LibLogFunctions>& GetLibLogFunctions();

View file

@ -211,26 +211,27 @@ static AbortFunction& Aborter() {
return aborter;
}
// Only used for Q fallback.
static std::recursive_mutex& TagLock() {
static auto& tag_lock = *new std::recursive_mutex();
return tag_lock;
}
// Only used for Q fallback.
static std::string* gDefaultTag;
std::string GetDefaultTag() {
std::lock_guard<std::recursive_mutex> lock(TagLock());
if (gDefaultTag == nullptr) {
return "";
}
return *gDefaultTag;
}
void SetDefaultTag(const std::string& tag) {
std::lock_guard<std::recursive_mutex> lock(TagLock());
if (gDefaultTag != nullptr) {
delete gDefaultTag;
gDefaultTag = nullptr;
}
if (!tag.empty()) {
gDefaultTag = new std::string(tag);
static auto& liblog_functions = GetLibLogFunctions();
if (liblog_functions) {
liblog_functions->__android_log_set_default_tag(tag.c_str());
} else {
std::lock_guard<std::recursive_mutex> lock(TagLock());
if (gDefaultTag != nullptr) {
delete gDefaultTag;
gDefaultTag = nullptr;
}
if (!tag.empty()) {
gDefaultTag = new std::string(tag);
}
}
}
@ -574,24 +575,18 @@ void LogMessage::LogLine(const char* file, unsigned int line, LogSeverity severi
const char* message) {
static auto& liblog_functions = GetLibLogFunctions();
auto priority = LogSeverityToPriority(severity);
if (tag == nullptr) {
std::lock_guard<std::recursive_mutex> lock(TagLock());
if (gDefaultTag == nullptr) {
gDefaultTag = new std::string(getprogname());
}
if (liblog_functions) {
__android_logger_data logger_data = {sizeof(__android_logger_data), LOG_ID_DEFAULT, priority,
gDefaultTag->c_str(), file, line};
__android_log_write_logger_data(&logger_data, message);
} else {
Logger()(DEFAULT, severity, gDefaultTag->c_str(), file, line, message);
}
if (liblog_functions) {
__android_logger_data logger_data = {
sizeof(__android_logger_data), LOG_ID_DEFAULT, priority, tag, file, line};
__android_log_write_logger_data(&logger_data, message);
} else {
if (liblog_functions) {
__android_logger_data logger_data = {
sizeof(__android_logger_data), LOG_ID_DEFAULT, priority, tag, file, line};
__android_log_write_logger_data(&logger_data, message);
if (tag == nullptr) {
std::lock_guard<std::recursive_mutex> lock(TagLock());
if (gDefaultTag == nullptr) {
gDefaultTag = new std::string(getprogname());
}
Logger()(DEFAULT, severity, gDefaultTag->c_str(), file, line, message);
} else {
Logger()(DEFAULT, severity, tag, file, line, message);
}

View file

@ -603,21 +603,6 @@ __attribute__((constructor)) void TestLoggingInConstructor() {
LOG(ERROR) << "foobar";
}
TEST(logging, SetDefaultTag) {
constexpr const char* expected_tag = "test_tag";
constexpr const char* expected_msg = "foobar";
CapturedStderr cap;
{
std::string old_default_tag = android::base::GetDefaultTag();
android::base::SetDefaultTag(expected_tag);
android::base::ScopedLogSeverity sls(android::base::LogSeverity::INFO);
LOG(INFO) << expected_msg;
android::base::SetDefaultTag(old_default_tag);
}
ASSERT_NO_FATAL_FAILURE(
CheckMessage(cap, android::base::LogSeverity::INFO, expected_msg, expected_tag));
}
TEST(logging, StdioLogger) {
CapturedStderr cap_err;
CapturedStdout cap_out;

View file

@ -276,6 +276,13 @@ int __android_log_set_minimum_priority(int priority);
*/
int __android_log_get_minimum_priority();
/**
* Sets the default tag if no tag is provided when writing a log message. Defaults to
* getprogname(). This truncates tag to the maximum log message size, though appropriate tags
* should be much smaller.
*/
void __android_log_set_default_tag(const char* tag);
#ifdef __cplusplus
}
#endif

View file

@ -73,6 +73,7 @@ LIGLOG_R { # introduced=30
__android_log_logd_logger;
__android_log_security_bswrite; # apex
__android_log_set_aborter;
__android_log_set_default_tag;
__android_log_set_logger;
__android_log_set_minimum_priority;
__android_log_stderr_logger;

View file

@ -16,6 +16,7 @@
#include <errno.h>
#include <inttypes.h>
#include <libgen.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
@ -31,6 +32,7 @@
#include <private/android_logger.h>
#include "android/log.h"
#include "log/log_read.h"
#include "logger.h"
#include "rwlock.h"
#include "uio.h"
@ -106,6 +108,45 @@ void __android_log_close() {
#endif
}
#if defined(__GLIBC__) || defined(_WIN32)
static const char* getprogname() {
#if defined(__GLIBC__)
return program_invocation_short_name;
#elif defined(_WIN32)
static bool first = true;
static char progname[MAX_PATH] = {};
if (first) {
char path[PATH_MAX + 1];
DWORD result = GetModuleFileName(nullptr, path, sizeof(path) - 1);
if (result == 0 || result == sizeof(path) - 1) return "";
path[PATH_MAX - 1] = 0;
char* path_basename = basename(path);
snprintf(progname, sizeof(progname), "%s", path_basename);
first = false;
}
return progname;
#endif
}
#endif
// It's possible for logging to happen during static initialization before our globals are
// initialized, so we place this std::string in a function such that it is initialized on the first
// call.
static std::string& GetDefaultTag() {
static std::string default_tag = getprogname();
return default_tag;
}
static RwLock default_tag_lock;
void __android_log_set_default_tag(const char* tag) {
auto lock = std::unique_lock{default_tag_lock};
GetDefaultTag().assign(tag, 0, LOGGER_ENTRY_MAX_PAYLOAD);
}
static int minimum_log_priority = ANDROID_LOG_DEFAULT;
int __android_log_set_minimum_priority(int priority) {
int old_minimum_log_priority = minimum_log_priority;
@ -270,7 +311,11 @@ int __android_log_write(int prio, const char* tag, const char* msg) {
}
void __android_log_write_logger_data(__android_logger_data* logger_data, const char* msg) {
if (logger_data->tag == nullptr) logger_data->tag = "";
auto tag_lock = std::shared_lock{default_tag_lock, std::defer_lock};
if (logger_data->tag == nullptr) {
tag_lock.lock();
logger_data->tag = GetDefaultTag().c_str();
}
#if __BIONIC__
if (logger_data->priority == ANDROID_LOG_FATAL) {

View file

@ -54,6 +54,7 @@ cc_defaults {
],
srcs: [
"libc_test.cpp",
"liblog_default_tag.cpp",
"liblog_global_state.cpp",
"liblog_test.cpp",
"log_id_test.cpp",

View file

@ -0,0 +1,99 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// LOG_TAG must be unset for android-base's logging to use a default tag.
#undef LOG_TAG
#include <stdlib.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android/log.h>
#include <gtest/gtest.h>
TEST(liblog_default_tag, no_default_tag_libbase_write_first) {
using namespace android::base;
bool message_seen = false;
std::string expected_tag = "";
SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
message_seen = true;
EXPECT_EQ(expected_tag, tag);
});
expected_tag = getprogname();
LOG(WARNING) << "message";
EXPECT_TRUE(message_seen);
message_seen = false;
__android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message");
EXPECT_TRUE(message_seen);
}
TEST(liblog_default_tag, no_default_tag_liblog_write_first) {
using namespace android::base;
bool message_seen = false;
std::string expected_tag = "";
SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
message_seen = true;
EXPECT_EQ(expected_tag, tag);
});
expected_tag = getprogname();
__android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message");
EXPECT_TRUE(message_seen);
message_seen = false;
LOG(WARNING) << "message";
EXPECT_TRUE(message_seen);
}
TEST(liblog_default_tag, libbase_sets_default_tag) {
using namespace android::base;
bool message_seen = false;
std::string expected_tag = "libbase_test_tag";
SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
message_seen = true;
EXPECT_EQ(expected_tag, tag);
});
SetDefaultTag(expected_tag);
__android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message");
EXPECT_TRUE(message_seen);
message_seen = false;
LOG(WARNING) << "message";
EXPECT_TRUE(message_seen);
}
TEST(liblog_default_tag, liblog_sets_default_tag) {
using namespace android::base;
bool message_seen = false;
std::string expected_tag = "liblog_test_tag";
SetLogger([&](LogId, LogSeverity, const char* tag, const char*, unsigned int, const char*) {
message_seen = true;
EXPECT_EQ(expected_tag, tag);
});
__android_log_set_default_tag(expected_tag.c_str());
__android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, nullptr, "message");
EXPECT_TRUE(message_seen);
message_seen = false;
LOG(WARNING) << "message";
EXPECT_TRUE(message_seen);
}