Sourceware Bugzilla – Attachment 8787 Details for
Bug 19243
reused_arena can pick an arena on the free list, leading to an assertion failure and reference count corruption
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
bug19243.c
tst.c (text/plain), 4.89 KB, created by
Florian Weimer
on 2015-11-16 20:18:30 UTC
(
hide
)
Description:
bug19243.c
Filename:
MIME Type:
Creator:
Florian Weimer
Created:
2015-11-16 20:18:30 UTC
Size:
4.89 KB
patch
obsolete
>/* Test malloc with concurrent thread creation and termination. > Copyright (C) 2015 Free Software Foundation, Inc. > This file is part of the GNU C Library. > > The GNU C Library is free software; you can redistribute it and/or > modify it under the terms of the GNU Lesser General Public > License as published by the Free Software Foundation; either > version 2.1 of the License, or (at your option) any later version. > > The GNU C Library is distributed in the hope that it will be useful, > but WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > Lesser General Public License for more details. > > You should have received a copy of the GNU Lesser General Public > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > >#include <errno.h> >#include <pthread.h> >#include <stdatomic.h> >#include <stdbool.h> >#include <stdio.h> >#include <stdlib.h> >#include <unistd.h> > >static void >usage (char **argv) >{ > fprintf (stderr, "usage: %s OUTER INNER TIMEOUT\n", argv[0]); > exit (2); >} > >static _Atomic bool termination_requested; >static int inner_count; >static size_t malloc_size = 32; > >static void >__attribute__ ((noinline, noclone)) >unoptimized_free (void *ptr) >{ > free (ptr); >} > >static void * >malloc_first_thread (void * closure) >{ > pthread_barrier_t *barrier = closure; > void *ptr = malloc (malloc_size); > if (ptr == NULL) > { > printf ("error: malloc: %m\n"); > abort (); > } > int ret = pthread_barrier_wait (barrier); > if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) > { > errno = ret; > printf ("error: pthread_barrier_wait: %m\n"); > abort (); > } > unoptimized_free (ptr); > return NULL; >} > >static void * >wait_first_thread (void * closure) >{ > pthread_barrier_t *barrier = closure; > int ret = pthread_barrier_wait (barrier); > if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) > { > errno = ret; > printf ("error: pthread_barrier_wait: %m\n"); > abort (); > } > void *ptr = malloc (malloc_size); > if (ptr == NULL) > { > printf ("error: malloc: %m\n"); > abort (); > } > unoptimized_free (ptr); > return NULL; >} > >static void * >outer_thread (void *closure) >{ > pthread_t *threads = calloc (sizeof (*threads), inner_count); > if (threads == NULL) > { > printf ("error: calloc: %m\n"); > abort (); > } > > while (!atomic_load_explicit (&termination_requested, > memory_order_relaxed)) { > pthread_barrier_t barrier; > int ret = pthread_barrier_init (&barrier, NULL, inner_count + 1); > if (ret != 0) > { > errno = ret; > printf ("pthread_barrier_init: %m\n"); > abort (); > } > for (int i = 0; i < inner_count; ++i) > { > void *(*func) (void *); > if ((i % 2) == 0) > func = malloc_first_thread; > else > func = wait_first_thread; > ret = pthread_create (threads + i, NULL, func, &barrier); > if (ret != 0) > { > errno = ret; > printf ("error: pthread_create: %m\n"); > abort (); > } > } > ret = pthread_barrier_wait (&barrier); > if (ret != 0 && ret != PTHREAD_BARRIER_SERIAL_THREAD) > { > errno = ret; > printf ("pthread_wait: %m\n"); > abort (); > } > for (int i = 0; i < inner_count; ++i) > { > ret = pthread_join (threads[i], NULL); > if (ret != 0) > { > ret = errno; > printf ("error: pthread_join: %m\n"); > abort (); > } > } > ret = pthread_barrier_destroy (&barrier); > if (ret != 0) > { > ret = errno; > printf ("pthread_barrier_destroy: %m\n"); > abort (); > } > } > > free (threads); > > return NULL; >} > >int >main (int argc, char **argv) >{ > if (argc != 4) > usage (argv); > int outer_count = atoi (argv[1]); > inner_count = atoi (argv[2]); > int timeout = atoi (argv[3]); > if ((inner_count % 2) != 0) > ++inner_count; > if (outer_count <= 0 || inner_count <= 0 || timeout <= 0) > usage (argv); > > pthread_t *threads = calloc (sizeof (*threads), outer_count); > if (threads == NULL) > { > printf ("error: calloc: %m\n"); > abort (); > } > > for (int i = 0; i < outer_count; ++i) > { > int ret = pthread_create (threads + i, NULL, outer_thread, NULL); > if (ret != 0) > { > errno = ret; > printf ("error: pthread_create: %m\n"); > abort (); > } > } > > struct timespec ts = {timeout, 0}; > if (nanosleep (&ts, NULL)) > { > printf ("error: error: nanosleep: %m\n"); > abort (); > } > > atomic_store_explicit (&termination_requested, true, memory_order_relaxed); > > for (int i = 0; i < outer_count; ++i) > { > int ret = pthread_join (threads[i], NULL); > if (ret != 0) > { > errno = ret; > printf ("error: pthread_join: %m\n"); > abort (); > } > } > free (threads); > > return 0; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 19243
: 8787