DF-5674 / race_attr.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | /* DF-5674 attribution: SIGSEGV handler that names the faulting symbol via dladdr */ #define _GNU_SOURCE #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ucontext.h> #include <dlfcn.h> #include <pthread.h> #include <libprop/proplib.h> #define NKEYS 96 #define NREMOVERS 3 #define NALLOCERS 2 #define ITERS 400000 static char keys[NKEYS][24]; static prop_string_t shared_str; static int do_remove = 1; static void segv(int sig, siginfo_t *si, void *uc) { ucontext_t *u = uc; Dl_info d; void *rip = (void *)(uintptr_t)u->uc_mcontext.mc_rip; if (dladdr(rip, &d) != 0 && d.dli_sname != NULL) fprintf(stderr, "SIGSEGV in %s (%s) addr=%p rip=%p\n", d.dli_sname, d.dli_fname, si->si_addr, rip); else fprintf(stderr, "SIGSEGV addr=%p rip=%p (no symbol)\n", si->si_addr, rip); _exit(139); } static void * remover(void *arg) { int it, i; for (it = 0; it < ITERS; it++) { prop_dictionary_t d = prop_dictionary_create(); if (d == NULL) break; for (i = 0; i < NKEYS; i++) prop_dictionary_set(d, keys[i], shared_str); if (do_remove) for (i = 0; i < NKEYS; i++) prop_dictionary_remove(d, keys[i]); prop_object_release(d); } return NULL; } static void * allocer(void *arg) { int it, i; for (it = 0; it < ITERS; it++) { prop_dictionary_t d = prop_dictionary_create(); if (d == NULL) break; for (i = 0; i < NKEYS; i++) prop_dictionary_set(d, keys[i], shared_str); prop_object_release(d); } return NULL; } int main(int argc, char **argv) { pthread_t thr[NREMOVERS + NALLOCERS]; struct sigaction sa; int i; if (argc > 1 && strcmp(argv[1], "noremove") == 0) do_remove = 0; memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = segv; sa.sa_flags = SA_SIGINFO; sigaction(SIGSEGV, &sa, NULL); sigaction(SIGBUS, &sa, NULL); for (i = 0; i < NKEYS; i++) snprintf(keys[i], sizeof(keys[i]), "key%04d", i * 7 % NKEYS); shared_str = prop_string_create_cstring("value"); { /* warm the global keysym tree */ prop_dictionary_t d = prop_dictionary_create(); for (i = 0; i < NKEYS; i++) prop_dictionary_set(d, keys[i], shared_str); prop_object_release(d); } for (i = 0; i < NREMOVERS; i++) pthread_create(&thr[i], NULL, remover, NULL); for (i = 0; i < NALLOCERS; i++) pthread_create(&thr[NREMOVERS + i], NULL, allocer, NULL); for (i = 0; i < NREMOVERS + NALLOCERS; i++) pthread_join(thr[i], NULL); printf("survived\n"); return 0; } |