Bug 160638 - pthread_cancel() crashes application.
pthread_cancel() crashes application.
Status: CLOSED DEFERRED
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: gcc (Show other bugs)
3.0
i686 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2005-06-16 04:35 EDT by Raj Devanesan
Modified: 2007-11-30 17:07 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2005-06-16 04:43:48 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Raj Devanesan 2005-06-16 04:35:26 EDT
Description of problem:


Calling pthread_cancel crashes the application, and core dumps. Same 
application build for previous versions of LINUX or solaris works fine. Any 
suggestions / details regarding this issue will be very helpful. At this point 
we are not able to move forward with AS 3.0 migration. 

While talking to my counterparts in NY, I found out that using /opt/gcc/... has 
some problems, so they recommended to use /usr/bin/g++. That solved the FATAL 
ERROR exception not rethrown error which I got earlier. But the crash still 
exists

Following is the code extract of the MsgThread class which wraps the thread_t 
and uses POSIX trhead funtions. 

#ifndef __MSG_THREAD_H__
#define __MSG_THREAD_H__

#include <pthread.h>
#include "MsgRunnable.h"
#include "MsgException.h"

/**
 *  A wrapper for pthread functions.
 *
 *  <pre>
 *  Date        Developer    Description
 *  ----------  -----------  --------------------------------------------------
 *  2001/08/06  nshibuya     created.
 *  </pre>
 */
class MsgThread
{
 public:
  /**
   * A thread is not alive before it is started.
   */
  MsgThread() : _isAlive( false ) {}

  /**
   * This starts a new thread and invokes the runnable instance.
   *
   * @param runnable an implementation of the MsgRunnable interface.
   *
   * @exception MsgException if fails to start a new thread.
   */
  void start( MsgRunnable* runnable, pthread_attr_t* attr = NULL ) throw 
(MsgException);

  /**
   * This stops the thread.
   */
  void stop() throw (MsgException);

  /**
   * This returns the thread alive status.
   *
   * @return true if the thread still alive.
   */
  msg_bool alive() const { return _isAlive; }  

 private:
  /**
   * A pthread variable.
   */
  pthread_t _thread;

  /**
   * An alive flag.
   */
  msg_bool _isAlive;
};

#endif


include "common/MsgThread.h"
#include "common/MsgLog.h"

//=============================================================================
// thread 
function //=====================================================================
========
extern "C" void* loop( void* data )
{
  MsgRunnable* runnable = (MsgRunnable*)data;

  try
  {
    runnable->run();
  }
  catch( MsgException& ex )
  {
    ex.printStackTrace();
  }
  catch( ... )
  {
    ERROR( "An unhandled error was thrown to the thread loop function" );
  }

  return NULL;
}

//=============================================================================
// start a thread 
//=============================================================================
void MsgThread::start( MsgRunnable* runnable, pthread_attr_t* attr ) throw 
(MsgException) {
  _isAlive = true;

  int error = pthread_create( &_thread, attr, loop, runnable );

  if( error )
  {
    THROW( "Failed to create a thread: error=" << error );
  }
}

//=============================================================================
// stop the 
thread //=======================================================================
======
void MsgThread::stop() throw (MsgException)
{
  _isAlive = false;

  int error = pthread_cancel( _thread );

  if( error )
  {
    THROW( "Failed to cancel the thread: error=" << error );
  }
}


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


How reproducible:


Steps to Reproduce:
1.
2.
3.
  
Actual results:


Expected results:


Additional info:
Comment 1 Jakub Jelinek 2005-06-16 04:43:48 EDT
You can't use catch (...) if you want cancellation to work (or you must
disable cancellation before the try block with catch (...) and reenable
it afterwards.
catch (...) blocks the cancellation.
There has been effort to resolve this, but because of the lack of standardization
of POSIX threads and C++ coexistence and because some C++ people insist that
catch (...) must also catch thread cancellation, while POSIX requires that
once cancellation starts, it must not be discarded, this resolving is currently
deadlocked.  If the POSIX and C++ committees ever sit together and decide what
the behaviour should be, this will change, but until then enabled thread
cancellation and catch (...) are incompatible.

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