Bug 77297 - pthread_cancel fails to exec all pthread_cleanup routines
Summary: pthread_cancel fails to exec all pthread_cleanup routines
Keywords:
Status: CLOSED UPSTREAM
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: glibc
Version: 7.2
Hardware: ia64
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Brian Brock
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2002-11-04 19:55 UTC by Need Real Name
Modified: 2016-11-24 14:49 UTC (History)
1 user (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2003-04-22 07:31:13 UTC
Embargoed:


Attachments (Terms of Use)

Description Need Real Name 2002-11-04 19:55:10 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.78C-SGI [en] (X11; U; IRIX 6.5-ALPHA-1277435220 IP22)

Description of problem:
I have run into a linuxthread problem that is caused by some (bad ?)
assumptions on stack address usage. The problem manifests itself in the
pthread_cleanup_push() and pthread_cleanup_pop() macros. The symptom of
the problem is that a pthread_cancel does not execute all of the
thread's cleanup routines if more than one routine gets pushed onto the
cleanup stack in the same subroutine.

The reason for the problem is that the pthread_cancel code that pops and
executes the cleanup 'stack' continues using the _prev value of each
pthread_cleanup frame until the stack address of the next frame is
greater|less than the current one based on a #define named either
STACK_GROWS_UP or STACK_GROWS_DOWN. I believe this is based on the
assumption that as you  progress down|up the stack by going into or
returning from subroutines, the stack does indeed grow down|up.

While in the same subroutine, however, the ordering of the
pthread_cleanup_buffer stack addresses as allocated by the
pthread_cleanup_push macro is indeterminate, at least it is on our IA64
platform.

I have simplified the problem into a short test case that uses the
bracketing and stack address allocation in the same manner that the
pthread_cleanup_push() and pthread_cleanup_pop() macros do. In my case,
we have STACK_GROW_DOWN defined, and as you can see the second stack
address is actually greater than the first. The pthread_cancel routine
would not execute the second cleanup subroutine put on the stack in this
case becuase the address comparison (FRAME_LEFT in
linuxthreads/cancel.c) would prohibit it.

I scanned the linux-ia64 archive for any discussion on this topic and
found none. I'm not sure if this problem is out there on any other IA64
platforms, either. I guess you can try the test case and see for
yourself.

Test program:

#include <stdio.h>
#include <malloc.h>

main(int argc, char **argv)
{
        printf("hello\n");
  {
    int x = 1;
    printf("x = %d, &x = %x\n", x, &x);

    {
      int y = 2;
      printf("y = %d, &y = %x\n", y, &y);
    }

  }
        printf("goodbye\n");

}

My results:

hello
x = 1, &x = ffffb4e0
y = 2, &y = ffffb4e4
goodbye



Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
See test code in description.
	

Additional info:

Comment 1 Ulrich Drepper 2003-04-22 07:31:13 UTC
There are always going to be some restrictions wrt to cleanup handlers (since
gcc doesn't implement exception handling for gcc) but almost all the cases are
handled correctly with NPTL.  The sources are in the official glibc archive and
will be used in the upcoming RHEL3 release on ia64.  There won't be a change for
old thread libraries.


Note You need to log in before you can comment on or make changes to this bug.