public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug nptl/11670] New: Variables defined in pthread_cleanup_push() macro may be optimised away which breaks __sigsetjmp
@ 2010-06-05  7:18 ceggers at gmx dot de
  2010-06-05  7:23 ` [Bug nptl/11670] " ceggers at gmx dot de
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: ceggers at gmx dot de @ 2010-06-05  7:18 UTC (permalink / raw)
  To: glibc-bugs

Please consider the following code snippset:

--- snipp ---
my_ptr = malloc(100);
pthread_cleanup_push(my_handler, my_ptr);
...
pthread_cleanup_pop(1);
--- /snipp ---

With -Os optimisation, the C equivalent of the optimised code can look similar
to this (pure C, __EXCEPTIONS not defined):

--- snipp ---
/* # define pthread_cleanup_push(routine, arg) */
  do {
    __pthread_unwind_buf_t __cancel_buf;
[OPTIMISED AWAY]void (*__cancel_routine) (void *) = (routine);
    void *__cancel_arg = (arg);
    int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) (void *)
				      __cancel_buf.__cancel_jmp_buf, 0);
    if (__builtin_expect (not_first_call, 0))
      {
	my_handler (__cancel_arg);  [__cancel_routine has been replaced by a fixed
function call]
	__pthread_unwind_next (&__cancel_buf);
	/* NOTREACHED */
      }

    __pthread_register_cancel (&__cancel_buf);
    do {

...
<User code>
[somewhere here the stack memory for __cancel_arg is "reused" by another
variable, because ...]
<User code>
...

/* # define pthread_cleanup_pop(execute) */
      do { } while (0);/* Empty to allow label before pthread_cleanup_pop.  */
    } while (0);
    __pthread_unregister_cancel (&__cancel_buf);
    if (execute)
      my_handler (my_ptr);  [... __cancel_arg has been merged with my_ptr]
  } while (0)
--- /snipp ---

The compiler seems to recognize that the content of my_ptr and __cancel_arg is
always the same, so there's no need to keep both on the stack. __cancel_arg in
pthread_cleanup_pop() is replaced by my_ptr.

As long as no cancellation happens everything is fine. my_handler() is always
called with the correct argument. But in case of cancellation siglongjmp() may
be called from a position after the stack memory for __cancel_arg has been
"reused". In this case __sigsetjmp() returns and my_handler() is called with
something different than the original value of my_ptr.

The problem is not limited to __cancel_arg, the same could also happen to
__cancel_buf or __cancel_routine (if not replaced by a fixed function call). I
think there's no guarantee that none of the three stack variables is discarded
between __pthread_register_cancel() and __pthread_unregister_cancel().

As a first try to solve this I've modified the macros so that they are more
similar to the variant used when __EXCEPTIONS is defined (using the __cleanup__
attribute from GCC). The result seems to work for me, but it's in the nature of
compiler optimisations that problems seems to be "disappeared" if something is
altered a little bit ...

-- 
           Summary: Variables defined in pthread_cleanup_push() macro may be
                    optimised away which breaks __sigsetjmp
           Product: glibc
           Version: 2.12
            Status: NEW
          Severity: normal
          Priority: P2
         Component: nptl
        AssignedTo: drepper at redhat dot com
        ReportedBy: ceggers at gmx dot de
                CC: glibc-bugs at sources dot redhat dot com
 GCC build triplet: x86_64-unknown-linux-gnu
  GCC host triplet: x86_64-unknown-linux-gnu
GCC target triplet: arm-arm920t-linux-gnueabi


http://sourceware.org/bugzilla/show_bug.cgi?id=11670

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


^ permalink raw reply	[flat|nested] 9+ messages in thread
[parent not found: <bug-11670-131@http.sourceware.org/bugzilla/>]

end of thread, other threads:[~2014-06-30 17:52 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-05  7:18 [Bug nptl/11670] New: Variables defined in pthread_cleanup_push() macro may be optimised away which breaks __sigsetjmp ceggers at gmx dot de
2010-06-05  7:23 ` [Bug nptl/11670] " ceggers at gmx dot de
2010-06-07  8:40 ` schwab at linux-m68k dot org
2010-06-07 12:05 ` christian dot eggers at kathrein dot de
2010-06-07 12:20 ` schwab at linux-m68k dot org
2010-06-07 12:26 ` schwab at linux-m68k dot org
2010-06-07 13:03 ` christian dot eggers at kathrein dot de
2010-06-07 13:12 ` jakub at redhat dot com
     [not found] <bug-11670-131@http.sourceware.org/bugzilla/>
2014-06-30 17:52 ` fweimer at redhat dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).