Merge "Silence -Wnon-power-of-two-alignment for a test"
diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp
index cf5cd82..227cb84 100644
--- a/libc/bionic/bionic_systrace.cpp
+++ b/libc/bionic/bionic_systrace.cpp
@@ -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 @@
   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 @@
   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 @@
   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);
 }
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 80d645a..53fe3d5 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -129,7 +129,8 @@
   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))) {
diff --git a/tests/struct_layout_test.cpp b/tests/struct_layout_test.cpp
index 00fd4d5..0123ed9 100644
--- a/tests/struct_layout_test.cpp
+++ b/tests/struct_layout_test.cpp
@@ -69,7 +69,8 @@
   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 @@
   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