md_doc_core_grpc-error.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
  5. <meta http-equiv="X-UA-Compatible" content="IE=9"/>
  6. <meta name="generator" content="Doxygen 1.8.17"/>
  7. <meta name="viewport" content="width=device-width, initial-scale=1"/>
  8. <title>GRPC Core: gRPC Error</title>
  9. <link href="tabs.css" rel="stylesheet" type="text/css"/>
  10. <script type="text/javascript" src="jquery.js"></script>
  11. <script type="text/javascript" src="dynsections.js"></script>
  12. <link href="search/search.css" rel="stylesheet" type="text/css"/>
  13. <script type="text/javascript" src="search/searchdata.js"></script>
  14. <script type="text/javascript" src="search/search.js"></script>
  15. <link href="doxygen.css" rel="stylesheet" type="text/css" />
  16. </head>
  17. <body>
  18. <div id="top"><!-- do not remove this div, it is closed by doxygen! -->
  19. <div id="titlearea">
  20. <table cellspacing="0" cellpadding="0">
  21. <tbody>
  22. <tr style="height: 56px;">
  23. <td id="projectalign" style="padding-left: 0.5em;">
  24. <div id="projectname">GRPC Core
  25. &#160;<span id="projectnumber">15.0.0</span>
  26. </div>
  27. </td>
  28. </tr>
  29. </tbody>
  30. </table>
  31. </div>
  32. <!-- end header part -->
  33. <!-- Generated by Doxygen 1.8.17 -->
  34. <script type="text/javascript">
  35. /* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  36. var searchBox = new SearchBox("searchBox", "search",false,'Search');
  37. /* @license-end */
  38. </script>
  39. <script type="text/javascript" src="menudata.js"></script>
  40. <script type="text/javascript" src="menu.js"></script>
  41. <script type="text/javascript">
  42. /* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  43. $(function() {
  44. initMenu('',true,false,'search.php','Search');
  45. $(document).ready(function() { init_search(); });
  46. });
  47. /* @license-end */</script>
  48. <div id="main-nav"></div>
  49. <!-- window showing the filter options -->
  50. <div id="MSearchSelectWindow"
  51. onmouseover="return searchBox.OnSearchSelectShow()"
  52. onmouseout="return searchBox.OnSearchSelectHide()"
  53. onkeydown="return searchBox.OnSearchSelectKey(event)">
  54. </div>
  55. <!-- iframe showing the search results (closed by default) -->
  56. <div id="MSearchResultsWindow">
  57. <iframe src="javascript:void(0)" frameborder="0"
  58. name="MSearchResults" id="MSearchResults">
  59. </iframe>
  60. </div>
  61. </div><!-- top -->
  62. <div class="PageDoc"><div class="header">
  63. <div class="headertitle">
  64. <div class="title">gRPC Error </div> </div>
  65. </div><!--header-->
  66. <div class="contents">
  67. <div class="textblock"><h1><a class="anchor" id="autotoc_md104"></a>
  68. Background</h1>
  69. <p><code>grpc_error</code> is the c-core's opaque representation of an error. It holds a collection of integers, strings, timestamps, and child errors that related to the final error.</p>
  70. <p>always present are:</p>
  71. <ul>
  72. <li>GRPC_ERROR_STR_FILE and GRPC_ERROR_INT_FILE_LINE - the source location where the error was generated</li>
  73. <li>GRPC_ERROR_STR_DESCRIPTION - a human readable description of the error</li>
  74. <li>GRPC_ERROR_TIME_CREATED - a timestamp indicating when the error happened</li>
  75. </ul>
  76. <p>An error can also have children; these are other errors that are believed to have contributed to this one. By accumulating children, we can begin to root cause high level failures from low level failures, without having to derive execution paths from log lines.</p>
  77. <p>grpc_errors are refcounted objects, which means they need strict ownership semantics. An extra ref on an error can cause a memory leak, and a missing ref can cause a crash.</p>
  78. <p>This document serves as a detailed overview of grpc_error's ownership rules. It should help people use the errors, as well as help people debug refcount related errors.</p>
  79. <h1><a class="anchor" id="autotoc_md105"></a>
  80. Clarification of Ownership</h1>
  81. <p>If a particular function is said to "own" an error, that means it has the responsibility of calling unref on the error. A function may have access to an error without ownership of it.</p>
  82. <p>This means the function may use the error, but must not call unref on it, since that will be done elsewhere in the code. A function that does not own an error may explicitly take ownership of it by manually calling GRPC_ERROR_REF.</p>
  83. <h1><a class="anchor" id="autotoc_md106"></a>
  84. Ownership Rules</h1>
  85. <p>There are three rules of error ownership, which we will go over in detail.</p>
  86. <ul>
  87. <li>If <code>grpc_error</code> is returned by a function, the caller owns a ref to that instance.</li>
  88. <li>If a <code>grpc_error</code> is passed to a <code>grpc_closure</code> callback function, then that function does not own a ref to the error.</li>
  89. <li>if a <code>grpc_error</code> is passed to <em>any other function</em>, then that function takes ownership of the error.</li>
  90. </ul>
  91. <h2><a class="anchor" id="autotoc_md107"></a>
  92. Rule 1</h2>
  93. <blockquote class="doxtable">
  94. <p>If <code>grpc_error</code> is returned by a function, the caller owns a ref to that instance.* </p>
  95. </blockquote>
  96. <p>For example, in the following code block, error1 and error2 are owned by the current function.</p>
  97. <div class="fragment"><div class="line">grpc_error* error1 = GRPC_ERROR_CREATE_FROM_STATIC_STRING(<span class="stringliteral">&quot;Some error occurred&quot;</span>);</div>
  98. <div class="line">grpc_error* error2 = some_operation_that_might_fail(...);</div>
  99. </div><!-- fragment --><p>The current function would have to explicitly call GRPC_ERROR_UNREF on the errors, or pass them along to a function that would take over the ownership.</p>
  100. <h2><a class="anchor" id="autotoc_md108"></a>
  101. Rule 2</h2>
  102. <blockquote class="doxtable">
  103. <p>If a <code>grpc_error</code> is passed to a <code>grpc_closure</code> callback function, then that function does not own a ref to the error. </p>
  104. </blockquote>
  105. <p>A <code>grpc_closure</code> callback function is any function that has the signature:</p>
  106. <div class="fragment"><div class="line">void (*cb)(grpc_exec_ctx *exec_ctx, <span class="keywordtype">void</span> *arg, grpc_error *error);</div>
  107. </div><!-- fragment --><p>This means that the error ownership is NOT transferred when a functions calls:</p>
  108. <div class="fragment"><div class="line">c-&gt;cb(exec_ctx, c-&gt;cb_arg, err);</div>
  109. </div><!-- fragment --><p>The caller is still responsible for unref-ing the error.</p>
  110. <p>However, the above line is currently being phased out! It is safer to invoke callbacks with <code>GRPC_CLOSURE_RUN</code> and <code>GRPC_CLOSURE_SCHED</code>. These functions are not callbacks, so they will take ownership of the error passed to them.</p>
  111. <div class="fragment"><div class="line">grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(<span class="stringliteral">&quot;Some error occurred&quot;</span>);</div>
  112. <div class="line">GRPC_CLOSURE_RUN(exec_ctx, cb, error);</div>
  113. <div class="line"><span class="comment">// current function no longer has ownership of the error</span></div>
  114. </div><!-- fragment --><p>If you schedule or run a closure, but still need ownership of the error, then you must explicitly take a reference.</p>
  115. <div class="fragment"><div class="line">grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(<span class="stringliteral">&quot;Some error occurred&quot;</span>);</div>
  116. <div class="line">GRPC_CLOSURE_RUN(exec_ctx, cb, GRPC_ERROR_REF(error));</div>
  117. <div class="line"><span class="comment">// do some other things with the error</span></div>
  118. <div class="line">GRPC_ERROR_UNREF(error);</div>
  119. </div><!-- fragment --><p>Rule 2 is more important to keep in mind when <b>implementing</b> <code>grpc_closure</code> callback functions. You must keep in mind that you do not own the error, and must not unref it. More importantly, you cannot pass it to any function that would take ownership of the error, without explicitly taking ownership yourself. For example:</p>
  120. <div class="fragment"><div class="line"><span class="keywordtype">void</span> on_some_action(grpc_exec_ctx *exec_ctx, <span class="keywordtype">void</span> *arg, grpc_error *error) {</div>
  121. <div class="line"> <span class="comment">// this would cause a crash, because some_function will unref the error,</span></div>
  122. <div class="line"> <span class="comment">// and the caller of this callback will also unref it.</span></div>
  123. <div class="line"> some_function(error);</div>
  124. <div class="line"> </div>
  125. <div class="line"> <span class="comment">// this callback function must take ownership, so it can give that</span></div>
  126. <div class="line"> <span class="comment">// ownership to the function it is calling.</span></div>
  127. <div class="line"> some_function(GRPC_ERROR_REF(error));</div>
  128. <div class="line">}</div>
  129. </div><!-- fragment --><h2><a class="anchor" id="autotoc_md109"></a>
  130. Rule 3</h2>
  131. <blockquote class="doxtable">
  132. <p>if a <code>grpc_error</code> is passed to <em>any other function</em>, then that function takes ownership of the error. </p>
  133. </blockquote>
  134. <p>Take the following example:</p>
  135. <div class="fragment"><div class="line">grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(<span class="stringliteral">&quot;Some error occurred&quot;</span>);</div>
  136. <div class="line"><span class="comment">// do some things</span></div>
  137. <div class="line">some_function(error);</div>
  138. <div class="line"><span class="comment">// can&#39;t use error anymore! might be gone.</span></div>
  139. </div><!-- fragment --><p>When some_function is called, it takes over the ownership of the error, and it will eventually unref it. So the caller can no longer safely use the error.</p>
  140. <p>If the caller needed to keep using the error (or passing it to other functions), if would have to take on a reference to it. This is a common pattern seen.</p>
  141. <div class="fragment"><div class="line"><span class="keywordtype">void</span> func() {</div>
  142. <div class="line"> grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(<span class="stringliteral">&quot;Some error&quot;</span>);</div>
  143. <div class="line"> some_function(GRPC_ERROR_REF(error));</div>
  144. <div class="line"> <span class="comment">// do things</span></div>
  145. <div class="line"> some_other_function(GRPC_ERROR_REF(error));</div>
  146. <div class="line"> <span class="comment">// do more things</span></div>
  147. <div class="line"> some_last_function(error);</div>
  148. <div class="line">}</div>
  149. </div><!-- fragment --><p>The last call takes ownership and will eventually give the error its final unref.</p>
  150. <p>When <b>implementing</b> a function that takes an error (and is not a <code>grpc_closure</code> callback function), you must ensure the error is unref-ed either by doing it explicitly with GRPC_ERROR_UNREF, or by passing the error to a function that takes over the ownership. </p>
  151. </div></div><!-- contents -->
  152. </div><!-- PageDoc -->
  153. <!-- start footer part -->
  154. <hr class="footer"/><address class="footer"><small>
  155. Generated on Wed Mar 3 2021 19:17:11 for GRPC Core by &#160;<a href="http://www.doxygen.org/index.html">
  156. <img class="footer" src="doxygen.png" alt="doxygen"/>
  157. </a> 1.8.17
  158. </small></address>
  159. </body>
  160. </html>