Suicidal-exception-handling.html 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <html lang="en">
  2. <head>
  3. <title>Suicidal exception handling - avram - a virtual machine code interpreter</title>
  4. <meta http-equiv="Content-Type" content="text/html">
  5. <meta name="description" content="avram - a virtual machine code interpreter">
  6. <meta name="generator" content="makeinfo 4.13">
  7. <link title="Top" rel="start" href="index.html#Top">
  8. <link rel="up" href="Working-around-library-misfeatures.html#Working-around-library-misfeatures" title="Working around library misfeatures">
  9. <link rel="prev" href="Memory-leaks.html#Memory-leaks" title="Memory leaks">
  10. <link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
  11. <meta http-equiv="Content-Style-Type" content="text/css">
  12. <style type="text/css"><!--
  13. pre.display { font-family:inherit }
  14. pre.format { font-family:inherit }
  15. pre.smalldisplay { font-family:inherit; font-size:smaller }
  16. pre.smallformat { font-family:inherit; font-size:smaller }
  17. pre.smallexample { font-size:smaller }
  18. pre.smalllisp { font-size:smaller }
  19. span.sc { font-variant:small-caps }
  20. span.roman { font-family:serif; font-weight:normal; }
  21. span.sansserif { font-family:sans-serif; font-weight:normal; }
  22. --></style>
  23. </head>
  24. <body>
  25. <div class="node">
  26. <a name="Suicidal-exception-handling"></a>
  27. <p>
  28. Previous:&nbsp;<a rel="previous" accesskey="p" href="Memory-leaks.html#Memory-leaks">Memory leaks</a>,
  29. Up:&nbsp;<a rel="up" accesskey="u" href="Working-around-library-misfeatures.html#Working-around-library-misfeatures">Working around library misfeatures</a>
  30. <hr>
  31. </div>
  32. <h5 class="subsubsection">3.9.3.3 Suicidal exception handling</h5>
  33. <p>An inconvenient characteristic of some external library functions is
  34. to terminate the program rather than returning an error status to the
  35. caller for routine events such as a failure of memory allocation.
  36. Although in many cases there is no simple workaround for this
  37. behavior, memory allocation failures at least can be detected and
  38. preventive action taken by using the functions described in this
  39. section.
  40. <p>The general approach is to use memory management functions from
  41. <samp><span class="file">mwrap.h</span></samp> as described previously (<a href="Memory-leaks.html#Memory-leaks">Memory leaks</a>), while
  42. additionally registering a return destination for a non-local jump to
  43. <a name="index-non_002dlocal-jumps-691"></a>be taken in the event of a memory overflow. The jump is taken when an
  44. external library function calls <code>malloc</code> or <code>realloc</code>
  45. unsuccessfully. The jump avoids passing control back to the library
  46. function, thereby denying it the opportunity to abort, but restores
  47. the context to that of the jump destination almost as if the library
  48. function and all of its intervening callers had returned normally.
  49. <p>The interface is similar to that of the standard <code>setjmp</code>
  50. <a name="index-setjmp-692"></a>function defined in the system header file <code>setjmp.h</code>, and in
  51. fact is built on it, but differs in that the client module does not
  52. explicitly refer to jump buffers. Instead, the <code>mwrap</code> module
  53. internally maintains a stack of return destinations.
  54. <p>If a jump is taken, it always goes to the most recently registered
  55. destination. It may revert to the previously registered destination
  56. only when the current one is cleared. This organization provides the
  57. necessary flexibility for multiple clients and recursion, but it
  58. necessitates a protocol whereby each registration of a destination
  59. must be explicitly cleared exactly once.
  60. <p>The following functions implement these two features.
  61. <div class="defun">
  62. &mdash; Function: int <b>avm_setjmp</b> ()<var><a name="index-avm_005fsetjmp-693"></a></var><br>
  63. <blockquote><p>This function specifies the point to which control will pass by a
  64. non-local jump if there is insufficient memory to complete a
  65. subsequent <code>malloc</code> or <code>realloc</code> operation. Only the
  66. operations that take place while memory is being managed due to
  67. <code>avm_manage_memory</code> are affected (<a href="Memory-leaks.html#Memory-leaks">Memory leaks</a>).
  68. <p>The function returns zero when it is called normally and successfully
  69. registers the return point.
  70. <p>It returns a non-zero value when it has been entered by a non-local
  71. jump (i.e., when <code>malloc</code> or <code>realloc</code> has reported
  72. insufficient memory while memory management is active), or when the
  73. return point could not be successfully registered due to insufficient
  74. memory. The client need not distinguish between these two cases,
  75. because both correspond to memory overflows and the destination must
  76. be cleared by <code>avm_clearjmp</code> regardless.
  77. <p>When a non-zero value is returned due to this function being reached
  78. by a non-local jump, it has the side effects of reclaiming all managed
  79. memory by calling <code>avm_free_managed_memory</code> and disabling memory
  80. management by calling <code>avm_dont_manage_memory</code>.
  81. </p></blockquote></div>
  82. <div class="defun">
  83. &mdash; Function: void <b>avm_clearjmp</b> ()<var><a name="index-avm_005fclearjmp-694"></a></var><br>
  84. <blockquote><p>This function cancels the effect of <code>avm_setjmp ()</code> by preventing
  85. further non-local jumps to its destination if the destination was
  86. successfully registered, or by acknowledging unsuccessful registration
  87. otherwise. It should be called before exiting any function that calls
  88. <code>avm_setjmp ()</code> or anomalous results may ensue.
  89. </p></blockquote></div>
  90. <p>The memory management functions <code>avm_manage_memory</code> and
  91. <code>avm_dont_manage_memory</code> can be useful with or without
  92. <code>avm_setjmp</code>, depending on how much of a workaround is needed for
  93. a given library. If a library does not abort on memory overflows,
  94. there is no need to use <code>avm_setjmp</code>, while it may still be
  95. appropriate to use the other functions against memory leaks.
  96. <p>Calling <code>avm_clearjmp</code> is particularly important if a client
  97. module with memory management that doesn't use <code>avm_setjmp</code> is
  98. invoked subsequently to one that does, so that memory overflows in the
  99. latter won't cause an attempted jump to a stale destination.
  100. <p>A further complication that arises from careful consideration of these
  101. issues is the situation of a client module that does not intend to use
  102. <code>avm_setjmp</code> but is called (perhaps indirectly) by one that
  103. does. The latter will have registered a return destination that
  104. remains active and valid even if the former refrains from doing so,
  105. thereby allowing a branch to be taken that should have been prevented.
  106. Although it is an unusual situation, it can be accommodated by the
  107. following function.
  108. <div class="defun">
  109. &mdash; Function: void <b>avm_setnonjump</b> ()<var><a name="index-avm_005fsetnonjump-695"></a></var><br>
  110. <blockquote><p>This function temporarily inhibits non-local jumps to destinations
  111. previously registered by <code>avm_setjmp</code> until the next time
  112. <code>avm_clearjmp</code> is called. Thereafter, any previously registered
  113. destinations are reinstated.
  114. </p></blockquote></div>
  115. <p>A sketch of how some of these functions might be used to cope with
  116. library functions that would otherwise terminate the program in the
  117. event of a memory overflow is shown below. The GNU <code>libc</code>
  118. <a name="index-non_002dlocal-jumps-696"></a>reference manual contains a related discussion of non-local jumps.
  119. <pre class="example"> #include &lt;avm/mwrap.h&gt;
  120. ...
  121. int
  122. function foobar (foo, bar)
  123. ...
  124. {
  125. char *my_data;
  126. my_data = (char *) malloc (100);
  127. if (avm_setjmp () != 0)
  128. {
  129. avm_clearjmp ();
  130. avm_turn_on_stdout (); /* reaching here */
  131. free (my_data); /* means malloc */
  132. return ABNORMAL_STATUS; /* failed below */
  133. }
  134. avm_turn_off_stdout ();
  135. avm_manage_memory ();
  136. ...
  137. call_library_functions (foo, bar); /* may jump */
  138. ... /* to above */
  139. avm_free_managed_memory ();
  140. avm_turn_on_stdout ();
  141. avm_clearjmp ();
  142. free (my_data); /* reaching here means */
  143. return OK_STATUS; /* jumping wasn't done */
  144. }
  145. </pre>
  146. <p>Portability issues with these functions are not well known at this
  147. <a name="index-portability-697"></a>writing. If the configuration script for <code>avram</code> fails to detect
  148. the required features in <code>setjmp.h</code> on the host system,
  149. conditional compilation directives will disable the functions
  150. <code>avm_setjmp</code>, <code>avm_clearjmp</code>, and <code>avm_setnonjmp</code>.
  151. However, it may still be possible for the other <code>avm_</code>* memory
  152. management functions to be configured.
  153. <p>If <code>setjmp</code> is not configured, the <code>avm_setjmp</code> function
  154. is still callable but will always return a value of zero, and will
  155. provide no protection against external library functions aborting the
  156. program. The other two will perform no operation and return.
  157. </body></html>