@@ -304,14 +304,33 @@ const char* getenv_or(const char* env, const char* def) {
304304std::atomic<bool > initializing{false };
305305std::atomic<bool > initialized{false };
306306
307+ const char * get_trace_path () {
308+ const char * path_ptr = getenv_or (" PTHREAD_TRACE_PATH" , " pthread_trace.proto" );
309+ // If running as a bazel test, and the path is not an absolute path, prepend
310+ // the test output directory to the path.
311+ if (path_ptr[0 ] == ' /' ) {
312+ return path_ptr;
313+ }
314+ const char * path_prefix_ptr = getenv_or (" TEST_UNDECLARED_OUTPUTS_DIR" , " " );
315+ static constexpr int path_buf_size = 4096 ;
316+ static char path_buf[path_buf_size];
317+ const int len =
318+ snprintf (path_buf, path_buf_size, " %s/%s" , path_prefix_ptr, path_ptr);
319+ if (len < 0 || len >= path_buf_size) {
320+ fprintf (stderr, " pthread_trace: Path too long or snprintf error.\n " );
321+ exit (1 );
322+ }
323+ return path_buf;
324+ }
325+
307326NOINLINE void init_trace () {
308327 // It seems like we could initialize the pthread_once hook, and use it here. However,
309328 // some pthread_once implementations use pthread_mutex internally (ask me how I know),
310329 // so we can't use that. We're just going to implement a call_once with spinning :(
311330
312331 bool not_initializing = false ;
313332 if (initializing.compare_exchange_strong (not_initializing, true )) {
314- const char * path = getenv_or ( " PTHREAD_TRACE_PATH " , " pthread_trace.proto " );
333+ const char * path = get_trace_path ( );
315334 const char * buffer_size_str = getenv_or (" PTHREAD_TRACE_BUFFER_SIZE_KB" , " 65536" );
316335 int buffer_size_kb = atoi (buffer_size_str);
317336 int blocks = (buffer_size_kb + block_size_kb - 1 ) / block_size_kb;
@@ -806,4 +825,4 @@ int sem_post(sem_t* sem) {
806825 return result;
807826}
808827
809- } // extern "C"
828+ } // extern "C"
0 commit comments