<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; "><br><div><div>On Jan 2, 2013, at 11:22 AM, Jordan Rose <<a href="mailto:jordan_rose@apple.com">jordan_rose@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><meta http-equiv="Content-Type" content="text/html charset=iso-8859-1"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Dec 27, 2012, at 14:31 , 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">Jordan,<br><br>Your explanation makes sense. It seems that the only piece missing from my previous patch is checking if the data is actually data know to come from malloc (or some other allocating function); if so and the region has an offset, then report the problem.<br>
<br>I find that there is something in the malloc checker which removes the symbol from a previous malloc from the RegionState map. Specifically, the checkPointerEscape callback. This was not used when I submitted my original patch, but was added since</blockquote><div><br></div><div>Yep, this has been recently added to handle a common pattern across checkers. Hopefully it just simplifies things and doesn't make other things more complicated.</div><div><br></div><br><blockquote type="cite"> It seems that this callback is invoked just before an invalidated symbol is passed to free. For example, the following results in a checkPointerEscape callback:<br>
<br><span style="font-family:courier new,monospace">{<br>int * data = malloc(sizeof(int));<br>data += 1;<br>free(data);<br>}</span><br><div class="gmail_quote"><br>However, If the correct pointer is given to free even if it is manipulated, checkPointerEscape is not called:<br>
<br><span style="font-family:courier new,monospace">{<br>int * array = malloc(sizeof(int)*5);<br>array += 1;<br>free(&array[-1]);<br>}</span><br><br>If checkPointerEscape removes the malloc information of an offending symbol from the RegionState map, then there is nothing to check inside of the FreeMemAux function called by the checkPostStmt callback. However, maybe it would be best to post a BugReport when the symbol is invalided, as that when the bug occurs. Do you know of anything the checkPointerEscape callback may catch that should not result in a BugReport if a malloc'ed symbol that is currently allocated is being invalidated?<br></div></blockquote><div><br></div><div>That sounds like a bug; checkPointerEscape should be called in both cases. (CC-ing Anna, who designed checkPointerEscape.) However, note that the checkPointerEscape callback does check to make sure that the function being called isn't free-like or malloc-like, so it shouldn't actually be causing any ill effects here. This is because it's called for <i>any</i> function call (see below).</div><div><br></div></div></div></blockquote><div><br></div><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><br><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><br><blockquote type="cite"><div class="gmail_quote">One more question. I notice that checkPointerEscape callback does not pass a CheckerContext, unlike the other checkers. Does this mean that a BugReport cannot be posted from within checkPointerEscape?<br></div></blockquote><div><br></div><div>That is<i> mostly</i> correct. Unlike other callbacks, checkPointerEscape does not allow you to create new nodes in the analyzer's state exploration graph, only to update the state along the current path. That's the main reason there's no CheckerContext. But it's also not reasonable to report a bug here, both because you don't have an ExplodedNode to attach the bug to (to give good path notes) and because symbols escape all the time, for a variety of reasons, and I can't see how you could <i>prove</i> that a particular escape constitutes a bug.</div><div><br></div><div>(Note that <i>escaping</i> is not the same thing as <i>leaking;</i> in fact, they are almost opposites. <i>Escaping</i> means the value may have been stored into long-term memory of some kind, or that it may have been freed by a helper function in a library somewhere, and so the analyzer can never really prove that the value has leaked.)</div><br><blockquote type="cite"><div class="gmail_quote"><br>- Branden<br></div></blockquote></div><br></div></blockquote></div><br></body></html>