Skip to content

Instantly share code, notes, and snippets.

@ddrown
Last active May 3, 2017 04:49
Show Gist options
  • Save ddrown/15e943b8fe1da398320b0c0518c95554 to your computer and use it in GitHub Desktop.
Save ddrown/15e943b8fe1da398320b0c0518c95554 to your computer and use it in GitHub Desktop.
uClibc-ng-1.0.17 pthread race condition crash
diff --git a/repo/toolchain/buildtool.cfg b/repo/toolchain/buildtool.cfg
index a07053b..c4cd0c4 100644
--- a/repo/toolchain/buildtool.cfg
+++ b/repo/toolchain/buildtool.cfg
@@ -69,6 +69,13 @@
Envname = UC_PATCH6
</File>
+<File sigaction-nop-pthread_cancel.patch>
+ Server = localrepo
+ Directory = toolchain
+ Revision = HEAD
+ Envname = UC_PATCH11
+</File>
+
# from buildtool.org
<File 850-libstdcxx-uclibc-c99.patch>
Server = localrepo
diff --git a/repo/toolchain/buildtool.mk b/repo/toolchain/buildtool.mk
index 0bf488e..86bc497 100644
--- a/repo/toolchain/buildtool.mk
+++ b/repo/toolchain/buildtool.mk
@@ -46,6 +46,7 @@ $(UCLIBC_DIR)/.source:
#cat $(UC_PATCH8) | patch -p1 -d $(UCLIBC_DIR)
#cat $(UC_PATCH9) | patch -p1 -d $(UCLIBC_DIR)
#cat $(UC_PATCH10) | patch -p1 -d $(UCLIBC_DIR)
+ cat $(UC_PATCH11) | patch -p0 -d $(UCLIBC_DIR)
touch $(UCLIBC_DIR)/.source
$(BINUTILS_DIR)/.source:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
/* This code is originally from https://github.com/ntp-project/ntp/blob/stable/ntpd/ntpd.c#L252
* running under uClibc-ng-1.0.17:
* # for i in `seq 1 10`; do ./ntpd-thread-test; done
* looks good
* looks good
* looks good
* looks good
* looks good
* looks good
* looks good
* Segmentation fault
* looks good
* looks good
*/
// note: this is only true for x86 platforms, can vary on other hardware
#define PTHREAD_STACK_MIN 16384
static void*
my_pthread_warmup_worker(
void *thread_args)
{
(void)thread_args;
for (;;)
sleep(10);
return NULL;
}
/* pre-heat threading: create a thread and cancel it, just to exercise
* thread cancellation.
*/
static void
my_pthread_warmup(void)
{
pthread_t thread;
pthread_attr_t thr_attr;
int rc;
pthread_attr_init(&thr_attr);
rc = pthread_attr_setstacksize(&thr_attr, PTHREAD_STACK_MIN);
if (0 != rc)
printf("my_pthread_warmup: pthread_attr_setstacksize() -> %s\n",
strerror(rc));
rc = pthread_create(&thread, &thr_attr, my_pthread_warmup_worker, NULL);
pthread_attr_destroy(&thr_attr);
if (0 != rc) {
printf("my_pthread_warmup: pthread_create() -> %s\n",
strerror(rc));
} else {
pthread_cancel(thread);
pthread_join(thread, NULL);
}
}
int main() {
my_pthread_warmup();
printf("looks good\n");
}
--- libc/sysdeps/linux/i386/sigaction.c.orig 2017-05-02 22:57:58.552332704 -0400
+++ libc/sysdeps/linux/i386/sigaction.c 2017-05-02 22:58:19.920574694 -0400
@@ -115,6 +115,7 @@
/* The return code for realtime-signals. */
# define RESTORE2(name, syscall) \
__asm__ ( \
+ " nop\n" \
".text\n" \
"__" #name ":\n" \
" movl $" #syscall ", %eax\n" \
@@ -128,6 +129,7 @@
# undef RESTORE2
# define RESTORE2(name, syscall) \
__asm__ ( \
+ " nop\n" \
".text\n" \
"__" #name ":\n" \
" popl %eax\n" \
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment