Change _stdio_handles_locking into _caller_handles_locking.
It is reported by tsan that funlockfile() can unlock an unlocked mutex.
It happens when printf() is called before fopen() or other stdio stuff.
As FLOCKFILE(fp) is called before __sinit(), _stdio_handles_locking is false,
and _FLOCK(fp) will not be locked. But then cantwrite(fp) in __vfprintf()
calls__sinit(), which makes _stdio_handles_locking become true, and
FUNLOCKFILE(fp) unlocks _FLOCK(fp).
Change _stdio_handles_locking into _caller_handles_locking,
so __sinit() won't change its value. Add test due to my previous fault.
Bug: 25392375
Change-Id: I483e3c3cdb28da65e62f1fd9615bf58c5403b4dd
diff --git a/tests/utils.h b/tests/utils.h
index 53cf6b6..9e77f24 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -18,6 +18,14 @@
#define __TEST_UTILS_H
#include <inttypes.h>
#include <sys/mman.h>
+#include <unistd.h>
+
+#include <atomic>
+#include <string>
+#include <regex>
+
+#include <base/file.h>
+#include <base/stringprintf.h>
#include "private/ScopeGuard.h"
@@ -82,4 +90,23 @@
}
};
+extern "C" pid_t gettid();
+
+static inline void WaitUntilThreadSleep(std::atomic<pid_t>& tid) {
+ while (tid == 0) {
+ usleep(1000);
+ }
+ std::string filename = android::base::StringPrintf("/proc/%d/stat", tid.load());
+ std::regex regex {R"(\s+S\s+)"};
+
+ while (true) {
+ std::string content;
+ ASSERT_TRUE(android::base::ReadFileToString(filename, &content));
+ if (std::regex_search(content, regex)) {
+ break;
+ }
+ usleep(1000);
+ }
+}
+
#endif