This is the mail archive of the cygwin mailing list for the Cygwin 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]

problem mixing C++ exceptions and setjmp/longjmp


I believe the following program should print

  main: calling doit
  doit: calling toit
  toit: throwing exception
  toit: caught exception, longjumping
  doit: longjump landed, throwing exception
  main: caught exception

but on the current Cygwin (updated today) using the 1.5.13-1
cygwin.dll and either gcc 3.3 or 3.4, it crashes with a segfault just
after printing the next to last line:

  doit: longjump landed, throwing exception

I tried going back to 1.5.12, but that did not fix the problem.

Can anyone reproduce this problem?

This problem affects GNU Octave, as it uses this technique to handle
interrupts in code that is a mixture of C++, C, and Fortran.  If
SIGINT arrives in a section of Octave code, the signal handler sets a
flag and then returns, letting Octave check the flag periodically.  At
some safe location, an exception is thrown that will return control
to the top level of the main interpreter loop.  If SIGINT arrives
inside some foreign code (say, readline, or some Fortran code) then
the signal handler jumps back to the location of the call to the
foreign code.  At that point, an exception is thrown to get back to
the top level.  I've not had problems with this approach until
recently when I upgraded my Cygwin installation.  Now Ctrl-C at the
prompt causes a segfault.  The program below is a distillation of the
key features of the Octave code, and shows the same problem.

Any clues?

Thanks,

jwe

-- 
www.octave.org | jwe@octave.org

#include <setjmp.h>

#include <iostream>

jmp_buf context;

class
exception
{
  // empty;
};

static void
toit (void)
{
  try
    {
      std::cerr << "toit: throwing exception" << std::endl;
      throw exception ();
    }
  catch (exception)
    {
      std::cerr << "toit: caught exception, longjumping" << std::endl;
      longjmp (context, 1);
    }
}

static void
doit (void)
{
  if (setjmp (context) == 0)
    {
      std::cerr << "doit: calling toit" << std::endl;
      toit ();
    }
  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;
}

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

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