polytracker
polytracker copied to clipboard
Call stack mismatch unwinding/handling
Peter pointed out that there might be a need for stack unwinding for setjmp/longjmp. We also have cases like in jq where pthread_once calls instrumented code creating a mismatch in the stack (returning to somewhere we are uncertain about).
Some things to think about
- We don't store events if there is a mismatch in the stack
- Does the call stack hold any valuable information we are missing? By having items in the call stack at exit time, are we missing extra return edges? I would say yeah I think?
- What are the cases that can cause stack not to be empty at exit? So far, setjmp/longjmp, pthread_once scenarios. etc.
- What should we do to handle this? On exit, just pop off? Or can we use what we know from the FuncCall events table (see #6363 ) to infer any missing edges? Is this optimal?
- I think you should investigate the level of effort to ensure matching events, that way there is a certain amount of uniformity in your data model. It's convenient to be able to always know there's a matching exit of some kind for every entry.
- This depends on when data gets "flushed." Do you wait until the end of a basic block to emit certain events that are collected over the course of a basic block? Otherwise, everything should be flushed, e.g. storing some tainted value to memory will have stored the taint to the shadow. Code that is skipped by
longjmp
is code that doesn't execute. - Besides
longjmp
, there's alsosiglongjmp
from inside a signal handler, as well as C++ exception throwing, which relies onlibunwind
on Linux, and will bounce all over the place in weird ways. - I think you should use a loop, pop off elements one at a time until you hit the matching function index. For each popped thing, emit a function exit event. Finally, in your
polytracker_end
function, you should unconditionally unwind all the stacks in a similar-ish way, or perhaps at least the current thread's stack. You could have three types of function exit events: return, skipped, exited.