Skip to content

Instantly share code, notes, and snippets.

@nwpierce
Created January 6, 2019 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nwpierce/df17c17571431a30c16999b6d0dd123f to your computer and use it in GitHub Desktop.
Save nwpierce/df17c17571431a30c16999b6d0dd123f to your computer and use it in GitHub Desktop.
alpine musl pthread_key_create bug
#include<stdio.h>
#include<pthread.h>
#include<assert.h>
/*
* first pass succeeds
*
* second pass succeeds on:
* Debian 9
* Ubuntu 18.10
* CentOS 7
* Mac OS X 10.13.6
* OpenBSD 6.3
*
* but fails on Alpine 3.8.1 / musl 1.1.19-r10:
*
* the first call to pthread_getspecific() after key creation returns the value set
* by the previous pass, instead of NULL. According to spec, I believe this to be
* incorrect behavior:
* http://pubs.opengroup.org/onlinepubs/007904975/functions/pthread_key_create.html
*
* Possibly related issues:
* https://www.google.com/search?q=%22lmdb%22+%22MDB_BAD_RSLOT%22+%22alpine%22
*
* compile with -DWORKAROUND to clear key value before deleting
*/
#ifdef WORKAROUND
#define pthread_key_delete(key) (pthread_setspecific((key), NULL),pthread_key_delete((key)))
#endif
/*
* create a new tls key
* ensure current value is NULL
* set a new value
* ensure current value was correctly updated
* delete tls key
*/
void test(char *label){
int rc;
pthread_key_t key;
void *ptr = (void *)test;
fprintf(stderr, "%s\n", label);
rc = pthread_key_create(&key, NULL);
assert(!rc);
void *val = pthread_getspecific(key);
assert(!val);
rc = pthread_setspecific(key, ptr);
assert(!rc);
val = pthread_getspecific(key);
assert(val == ptr);
rc = pthread_key_delete(key);
assert(!rc);
}
int main(int argc, char **argv){
test("pass 1");
test("pass 2");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment