Re: [gtk-list] Re: cannot longjmp from g_log_set_handler function



On 27 Mar 1999, Owen Taylor wrote:

> 
> Andrew Thomas <andrew@cogent.ca> writes:
> 
> > I created an error handler using g_log_set_handler that calls the
> > error handler for a language interpreter.  The action of the
> > interpreter is to throw an error, which entails a longjmp.  The
> > next time an error occurs in a GTK+ function, the error handler
> > enters again, where a global flag in the log routines says that
> > the second entry is a recursion (falsely), due to some code that
> > sets a global flag in the g_ error handler but never clears it on
> > a longjmp.
> > 
> > I suggest that there needs to be a function that will clean up
> > the error handler context in the event of a longjmp, so that it
> > is possible to throw GTK+ errors.  At the moment, the g_log_
> > function is only good for aborting a run, not for recovery.
> 
> Yep.
> 
> I'm not at all sure if I like the idea of somebody 
> long-jumping out of a g_error()
> 
>  - You will almost certainly leak memory. 
> 
>  - You may well leave GTK+ in an inconsistent state
>    that and may well get segfaults if you continue 
>    using GTK+
> 
> g_error indicates fatal errors. 
> 
>                                         Owen
> 
> P.S. - yes, exception handling is nice; but the only
> way to do it safely in C, IMO,  is to make all functions
> take another parameter, and you'll end up easily
> doubling the length and complexity of your code if
> you do that.

there are better ways to get exception handling in C code done, g_error()
is just not the right thing for this.
g_error() - exit the application due to an error condition and be so kind as
            to inform the user _why_ this happened.

if you want to get something like this along with g_log facilities, use your
own my_throw_exception() and invoke g_log() directly from within your
exception handler, probably as g_warning() or along with some privately defined
log level, e.g.

#define LOG_EXCEPTION (1  << G_LOG_LEVEL_USER_SHIFT)
extern inline void my_throw_exception (const gchar *format,
	                               ...) G_GNUC_PRINTF (1, 2);

extern inline void
my_throw_exception (const gchar *format,
                    ...)
{
  va_list args;
  va_start (args, format);
  g_logv (NULL, LOG_EXCEPTION, format, args);
  va_end (args);

  /* do longjmp() stuff here */
}

> 
> -- 
> To unsubscribe: mail -s unsubscribe gtk-list-request@redhat.com < /dev/null
> 
> 

---
ciaoTJ



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]