This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/20442] [3.3/3.4/4.0 Regression] problem mixing C++ exceptions and setjmp/longjmp with SJLJ exceptions


------- Additional Comments From paulthomas2 at wanadoo dot fr  2005-03-27 06:19 -------
(In reply to comment #0)
Recent correspondence between John Eaton and me.
______________________________________________________________
On 25-Mar-2005, Paul Thomas paulthomas2 at wanadoo dot fr wrote:

| Well, we have a response on the more recent bug - it's a bit negative 
| insofar as the advice is don't do what you're doing - it might appear to 
| work but, in fact, does not.  I have replied to say that I am consulting 
| with you and might or might not scrub the PR.

OK.

| > ------- Additional Comments From rth at gcc dot gnu dot org  2005-03-24 
| > 22:34 -------
| > Sorry, but this test case is never going to work -- with either sjlj 
| > exceptions
| > or unwind exceptions.  By longjmp-ing from the middle of a catch clause, 
| > you've
| > left the c++ library with live exceptions hanging around in global state. 
| > With
| > unwind exceptions it may appear to work, but is sure to fail in subtle 
| > ways.

So should it be OK to move the longjmp outside the catch clause?
For example, to simply set a flag inside the catch clause and call
longjmp later?  Note that doing that in my example program still
fails.  Try the new version below.  If you define CRASHME, it will
fail, and the longjmp is called outside the catch clause.  If you
don't define CRASHME, the longjmp happens in a completely separate
function and it appears to work (tested on a Cygwin system with the
current GCC).

In Octave, I think I can move the call to longjmp outside the catch
clause without too much trouble, but I don't think I can easily move
it to a completely separate function.

| > What I would strongly recommend is using either setjmp or
| > exceptions, but not both.

Perhaps I'm misunderstanding precisely what is meant by this.  If it
is that one should never use setjmp and exceptions in the same
program, then I don't think this is a realistic solution given that
real programs often mix code from various sources.  If I'm writing C++
and prefer to use exceptions, then I can't call any library code that
might happen to use setjmp somewhere along the way?

jwe


#include <csetjmp>

#include <iostream>

jmp_buf context;

class
exception
{
  // empty;
};

static bool do_longjump_return = false;

static void
callback_fcn (void)
{
  try
    {
      std::cerr << "toit: throwing exception" << std::endl;
      throw exception ();
    }
  catch (exception)
    {
      do_longjump_return = true;
      std::cerr << "toit: caught exception, preparing to longjump"
<< std::endl;
    }

#if defined (CRASHME)
  if (do_longjump_return)
    {
      std::cerr << "foreign code: exception in callback, longjumping"
<< std::endl;
      longjmp (context, 1);
    }
#endif
}

typedef void (*fptr) (void);

void
foreign_code (fptr f)
{
  std::cerr << "foreign code: executing callback" << std::endl;

  (*f) ();

#if ! defined (CRASHME)
  if (do_longjump_return)
    {
      std::cerr << "foreign code: exception in callback, longjumping"
<< std::endl;
      longjmp (context, 1);
    }
#endif
}

static void
doit (void)
{
  if (setjmp (context) == 0)
    {
      std::cerr << "doit: calling foreign code that uses callback_fcn"
<< std::endl;
      foreign_code (callback_fcn);
    }
  else
    {
      std::cerr << "doit: longjump landed, throwing exception" << std::endl;
      throw exception ();
    }
}

int
main (void)
{
  try
    {
      std::cerr << "main: calling doit" << std::endl;
      doit ();
    }
  catch (exception)
    {
      std::cerr << "main: caught exception" << std::endl;
    }

  return 0;
}



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20442


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]