[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: abort() calls

From: Jonathan Gilbert <o2w9gs702_at_sneakemail.com>
Date: 2007-05-01 03:07:49 CEST

At 08:22 PM 4/30/2007 +0200, Brane wrote:
>Jonathan Gilbert wrote:
>> What about -- on platforms that support it -- allowing the project calling
>> into the library to provide a jmp_buf to be longjmp()ed to instead of
>> abort()ing, and replacing the abort() calls with calls to a wrapper
>> function to pick between that and abort() if the user hasn't provided a
>> jmp_buf (or the platform doesn't support it)?
>>
>
>The number of implicit +1s to this proposal really make hair stand on end.
>
>The following really applies to any kind of abort() alternative, but
>longjmp sticks out.
>
> * How do you get the right jmp_buf to all the necessary places in
> all the Subversion libraries? we don't pass around a context
> object where it could be stored.

If it is added to libsvn_subr, is that not available from every other part
of Subversion? It can't be that hard to find one central place to put it.

> * What do you do with dangling resources (open files, etc.) that
> can't be cleaned up after a longjmp?

I thought Subversion allocated everything in APR pools. Won't that take
care of this? If a caller places his setjmp() in such a way that he loses
pointers to allocated objects when the longjmp() occurs, well, that's his
problem; he has the option of placing it right next to the Subversion
library and not having a problem.

> * How do you safely do /anything/ but end the process after you
> catch a longjmp?

By being careful when you use it. Just don't skip releasing your resources!

If you don't want to handle the error yourself, the solution is simple:

{
  jmp_buf *original_jmp_buf;
  jmp_buf my_jmp_buf;
  FILE *foobar = NULL;
  void *memory_block;

  if (setjmp(my_jmp_buf))
    {
      /* Release resources. */
      if (foobar)
        fclose(foobar);

      free(memory_block);

      /* Chain to the caller. */
      if (original_jmp_buf)
        longjmp(*original_jmp_buf, 1);
      else
        abort();
    }

  /* Start protected region. */
  original_jmp_buf =
    svn_set_emergency_exit_handler(&my_jmp_buf);

  /* Do stuff such as opening files or allocating memory. */
  ..
  ..

  /* End protected region. */
  svn_set_emergency_exit_handler(original_jmp_buf);
}

Where is the danger here?

Jonathan Gilbert

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue May 1 03:08:02 2007

This is an archived mail posted to the Subversion Dev mailing list.