Merge "Fix recursive deadlock inside bionic_systrace" am: f7e721cdc9 am: deb0f9972a

Original change: https://android-review.googlesource.com/c/platform/bionic/+/1958831

Change-Id: Ieeba1b3014200bd1fc4491e36d94c65c40ca5f81
This commit is contained in:
Daniele Di Proietto 2022-01-26 23:49:59 +00:00 committed by Automerger Merge Worker
commit 9ebbba014a
3 changed files with 40 additions and 5 deletions

View file

@ -20,8 +20,10 @@
#include <stdlib.h>
#include <string.h>
#include "bionic/pthread_internal.h"
#include "private/bionic_lock.h"
#include "private/bionic_systrace.h"
#include "private/bionic_tls.h"
#include "private/CachedProperty.h"
#include <async_safe/log.h>
@ -55,7 +57,7 @@ static int get_trace_marker_fd() {
return g_trace_marker_fd;
}
void bionic_trace_begin(const char* message) {
static void trace_begin_internal(const char* message) {
if (!should_trace()) {
return;
}
@ -76,7 +78,22 @@ void bionic_trace_begin(const char* message) {
TEMP_FAILURE_RETRY(write(trace_marker_fd, buf, len));
}
void bionic_trace_end() {
void bionic_trace_begin(const char* message) {
// Some functions called by trace_begin_internal() can call
// bionic_trace_begin(). Prevent infinite recursion and non-recursive mutex
// deadlock by using a flag in the thread local storage.
bionic_tls& tls = __get_bionic_tls();
if (tls.bionic_systrace_disabled) {
return;
}
tls.bionic_systrace_disabled = true;
trace_begin_internal(message);
tls.bionic_systrace_disabled = false;
}
static void trace_end_internal() {
if (!should_trace()) {
return;
}
@ -103,6 +120,21 @@ void bionic_trace_end() {
TEMP_FAILURE_RETRY(write(trace_marker_fd, const_cast<const char*>(buf), 2));
}
void bionic_trace_end() {
// Some functions called by trace_end_internal() can call
// bionic_trace_begin(). Prevent infinite recursion and non-recursive mutex
// deadlock by using a flag in the thread local storage.
bionic_tls& tls = __get_bionic_tls();
if (tls.bionic_systrace_disabled) {
return;
}
tls.bionic_systrace_disabled = true;
trace_end_internal();
tls.bionic_systrace_disabled = false;
}
ScopedTrace::ScopedTrace(const char* message) : called_end_(false) {
bionic_trace_begin(message);
}

View file

@ -129,7 +129,8 @@ struct bionic_tls {
passwd_state_t passwd;
char fdtrack_disabled;
char padding[3];
char bionic_systrace_disabled;
char padding[2];
// Initialize the main thread's final object using its bootstrap object.
void copy_from_bootstrap(const bionic_tls* boot __attribute__((unused))) {

View file

@ -69,7 +69,8 @@ void tests(CheckSize check_size, CheckOffset check_offset) {
CHECK_OFFSET(bionic_tls, group, 11952);
CHECK_OFFSET(bionic_tls, passwd, 12040);
CHECK_OFFSET(bionic_tls, fdtrack_disabled, 12192);
CHECK_OFFSET(bionic_tls, padding, 12193);
CHECK_OFFSET(bionic_tls, bionic_systrace_disabled, 12193);
CHECK_OFFSET(bionic_tls, padding, 12194);
#else
CHECK_SIZE(pthread_internal_t, 668);
CHECK_OFFSET(pthread_internal_t, next, 0);
@ -110,7 +111,8 @@ void tests(CheckSize check_size, CheckOffset check_offset) {
CHECK_OFFSET(bionic_tls, group, 10892);
CHECK_OFFSET(bionic_tls, passwd, 10952);
CHECK_OFFSET(bionic_tls, fdtrack_disabled, 11076);
CHECK_OFFSET(bionic_tls, padding, 11077);
CHECK_OFFSET(bionic_tls, bionic_systrace_disabled, 11077);
CHECK_OFFSET(bionic_tls, padding, 11078);
#endif // __LP64__
#undef CHECK_SIZE
#undef CHECK_OFFSET