<html><head><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I'll first summarize what is happening:<div><br><div>Example 1:</div><div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><blockquote type="cite"><span style="font-family: 'courier new', monospace; ">{<br>int * data = malloc(sizeof(int));<br>data += 1;<br>free(data);<br>}</span></blockquote></div></blockquote></div></blockquote></div></blockquote></div></blockquote></div></blockquote><br></div><div>In this case, checkPointerEscape is called, while evaluating a call to 'free'. The Call argument is NULL. Currently, we set Call to NULL unless the pointer is one of the arguments to the call, which is not the case here. The reason why we invalidate the pointer anyway is because we call a function that takes a pointer (data+1), from which our tracked pointer is accessible. This is pessimistic logic, which protects us from false positives. For example, we could have called some foo which would invalidate the pointer and anything accessible from it through pointer arithmetic. In the case at hand, we know that free is not going to do that, but currently this is not special cased. </div><div><br></div><div>The discussion below is about how we could special case it. Ex: check the callback to actually pass the Call parameter and use another argument to specify if the invalidation is direct (a pointer is an argument) or not. I am not sure how generic this solution is and how important it is to handle this. </div><div><br></div><div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><blockquote type="cite"><div class="gmail_quote"><span style="font-family: 'courier new', monospace; ">{<br>int * array = malloc(sizeof(int)*5);<br>array += 1;<br>free(&array[-1]);<br>}</span></div></blockquote></div></blockquote></div></blockquote></div></blockquote></div></blockquote></div></blockquote><div><br></div>In this case the callback is called. Inside the Malloc checker, we detect that the pointer is being invalidated because of a call to free. Malloc checker still wants to track the pointer since it knows the semantics of free, so we return early from the callback:</div><div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114); "><span style="color: #000000">  </span>// If we know that the call does not free memory, keep tracking the top</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; color: rgb(78, 144, 114); "><span style="color: #000000">  </span>// level arguments.       </div><div style="margin: 0px; font-size: 11px; font-family: Monaco; ">  <span style="color: #931a68">if</span> (Call && doesNotFreeMemory(Call, State))</div><div style="margin: 0px; font-size: 11px; font-family: Monaco; ">    <span style="color: #931a68">return</span> State;</div><div><br></div><div><div>On Jan 2, 2013, at 8:08 PM, Branden Archer <<a href="mailto:b.m.archer4@gmail.com">b.m.archer4@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">I am trying to catch up to your discussion. <br><br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>
I debugged the examples. The callback is called in both cases.</div><div><br></div><div>In the second case, we correctly determine that the pointer is being freed.</div><div><br></div><div>In the first case, we are not as precise as we could be. We decide that the pointer escapes, when 'data' is passed to 'free'. This is part of general pessimistic logic, which decides that everything accessible though a pointer passed to a function can escape. In this case, we could have added more logic to assume that 'free' does not invalidate any pointers. In order to do this, we would need to extend the pointerEscapes callback with a bool that let's us know if the invalidation is direct or not. Currently, we always set Call to NULL, when the invalidation is indirect.</div>
<div class="im"><br></div></div></blockquote></div><br>Oops. You are correct, the callback is being called for both cases. My mistake. <br><br>I am observing that the callback is unable to determine what type of non-function call based escape has occurred. For example, the second case is one example:<br>
<br><span style="font-family:courier new,monospace">  int * data = malloc(sizeof(int)*2);<br>  data += 1;<br>  free(data);</span><br><br>For that example, I am assuming the callback is being invoked when the pointer is being changed, but before it is passed to a function. </blockquote><div><br></div><div>It is called when evaluating the function. See the explanation above.</div><br><blockquote type="cite">Or maybe it is occurring when free is being called with an invalid pointer. The callback does not mention a function, setting Call to NULL, so I am not sure.</blockquote><blockquote type="cite"> Another example that results in a NULL Call is passing <span style="font-family:courier new,monospace">data</span> to a global structure. Passing the pointer to a global structure is quite fine, but it is indistinguishable from the problem case I am interested in detecting in example 2.<br>
<br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote"><div><br></div><div>Free is special but neither the MallocChecker nor the callback are dealing with it.</div>
<div><br></div><div>- The callback could pass non-NULL Call and a special flag saying that the invalidation is not direct.</div>-
 The malloc could check if Call is to 'free' and never act upon a 
pointer escape if it is. This could probably be generalized for other 
functions we know about. Ex, it's not malloc checker or 'free' specific -
 we always know that 'free' could only touch the argument. It might be 
better to find a more general solution for this. <br></blockquote><div><br>It is not clear to me in which cases the callback will be invoked when the escape is not due to a function call. That is, what is the difference between a 'direct' and 'indirect' invalidation.  <br></div></blockquote><div><br></div><div>Direct invalidation is when the pointer is one of the arguments. Indirect is everything else: assigned to a global, accessible though one of the arguments and more. We could change the callback to be more specific, however, there were no need for it so far.</div><br><blockquote type="cite"><div>
<br>I think that the solution you propose may work. That is, passing a non-NULL Call and a flag (to distinguish example 2 from other situations). For my curiosity, what are some examples where the Call would still be NULL, and would the value of the flag matter in such a case?<br>
<br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">The invalidation does happen (same as before). However, ideally, we would not invalidate and report a leak in example 1.<br>
</blockquote><br>What criteria is being used to determine if a pointer is to be invalidated?<br><br>- Branden<br></div>
</blockquote></div><br></div></div></body></html>