Skip to content

Commit 40deed0

Browse files
rmacnak-googleCommit Queue
authored andcommitted
[test] Avoid race in glibc's pthread_detach.
``` if (atomic_compare_and_exchange_bool_acq (&pd->joinid, pd, NULL)) { if (IS_DETACHED (pd)) ``` If the thread exits between these two statements, it will destroy the TCB and the second statement will segfault. TEST=ffi/async_void_function_callbacks_test Change-Id: If4074c89ec2a618b69f1a1ef3300b8aef7527ef7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/424380 Reviewed-by: Daco Harkes <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent 087ba40 commit 40deed0

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

runtime/bin/ffi_test/ffi_test_functions.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,11 +1326,49 @@ DART_EXPORT void CallFunctionOnNewThreadBlocking(int64_t response_id,
13261326
thread.join();
13271327
}
13281328

1329+
#if defined(__linux__)
1330+
struct Data {
1331+
void (*fn)(int64_t, int32_t);
1332+
int64_t a;
1333+
int32_t b;
1334+
};
1335+
static void* Start(void* data_in) {
1336+
Data* data = reinterpret_cast<Data*>(data_in);
1337+
void (*fn)(int64_t, int32_t) = data->fn;
1338+
int64_t a = data->a;
1339+
int64_t b = data->b;
1340+
delete data;
1341+
fn(a, b);
1342+
return nullptr;
1343+
}
1344+
#endif
1345+
13291346
DART_EXPORT void CallFunctionOnNewThreadNonBlocking(int64_t response_id,
13301347
void (*fn)(int64_t,
13311348
int32_t)) {
1349+
#if defined(__linux__)
1350+
// std::thread::detach is implemented via pthread_detach, which contains a
1351+
// race. https://sourceware.org/bugzilla/show_bug.cgi?id=19951
1352+
1353+
Data* data = new Data;
1354+
data->fn = fn;
1355+
data->a = response_id;
1356+
data->b = 123;
1357+
1358+
pthread_attr_t attr;
1359+
int result = pthread_attr_init(&attr);
1360+
if (result != 0) perror("pthread_attr_init");
1361+
result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
1362+
if (result != 0) perror("pthread_attr_setdetachstate");
1363+
pthread_t tid;
1364+
result = pthread_create(&tid, &attr, Start, data);
1365+
if (result != 0) perror("pthread_create");
1366+
result = pthread_attr_destroy(&attr);
1367+
if (result != 0) perror("pthread_attr_destroy");
1368+
#else
13321369
std::thread thread(fn, response_id, 123);
13331370
thread.detach();
1371+
#endif
13341372
}
13351373

13361374
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)