public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* [Bug uprobes/10078] New: uretprobes: longjmp fix broke funcs returning structs
@ 2009-04-16 23:15 jkenisto at us dot ibm dot com
  2009-04-21  0:07 ` [Bug uprobes/10078] " jkenisto at us dot ibm dot com
  0 siblings, 1 reply; 2+ messages in thread
From: jkenisto at us dot ibm dot com @ 2009-04-16 23:15 UTC (permalink / raw)
  To: systemtap

The fix for bug #5274 (uprobes: Handle longjmps) broke uretprobes
for functions that return structs or unions -- at least on x86_32
(not on x86_64).

This can be demonstrated by applying return probes to all functions
in zsh.  zsh dies rather quickly after starting up.  The failure
can be tracked to functions such as signal_block() and matheval(),
which return structs.

longjmp handling involves predicting what the stack pointer will be
upon return from each uretprobed function.  uretprobe_instances with
predicted stack pointers beyond the top of the stack are assumed
to represent functions that have been bypassed by longjmp, and
they're discarded.  The x86 prediction function assumes that every
function will return with a simple "ret" instruction (popping just the
return address).  But a function that returns a struct/union returns
with "ret $4" (pop return address AND pop 4 more bytes) on x86_32.
I missed this tidbit when I proposed the fix for #5274.

Three fixes come to mind:
1. Add a field to struct uretprobe that specifies the number of
"extra" bytes that the return instruction will pop (or just a
boolean field that indicates "returns a struct/union").  The
translator should be able to figure this out from the dwarf, but
lacking dwarf we're in trouble.

2. Allow 4 bytes of slop when deciding whether to bypass a function
instance, and hope that no function that should be bypassed has a
stack frame that consists only of the return address.

3. Like #1, but make register_uretprobe() figure it out.  Start at
the function entry point (rp->u.vaddr) and scan instructions until
you find a simple ret (opcode 0xc3) or a "ret $n" (opcode 0xc2).
(Assume that all returns in the function match in this regard.)
Of course, this requires instruction-analysis code like that used by
Masami in his recent kprobes safety enhancement.  And there are
functions that contain no returns at all -- they just jump to
another function, with both functions sharing the same return
address.

-- 
           Summary: uretprobes: longjmp fix broke funcs returning structs
           Product: systemtap
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: uprobes
        AssignedTo: systemtap at sources dot redhat dot com
        ReportedBy: jkenisto at us dot ibm dot com


http://sourceware.org/bugzilla/show_bug.cgi?id=10078

------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Bug uprobes/10078] uretprobes: longjmp fix broke funcs returning structs
  2009-04-16 23:15 [Bug uprobes/10078] New: uretprobes: longjmp fix broke funcs returning structs jkenisto at us dot ibm dot com
@ 2009-04-21  0:07 ` jkenisto at us dot ibm dot com
  0 siblings, 0 replies; 2+ messages in thread
From: jkenisto at us dot ibm dot com @ 2009-04-21  0:07 UTC (permalink / raw)
  To: systemtap


------- Additional Comments From jkenisto at us dot ibm dot com  2009-04-21 00:06 -------
This doesn't affect x86_64, powerpc, or s390 -- if the ABI docs are correct.

After discussing this with FChE, I've checked in Fix #2 for x86_32 -- commit
436e5bf.  This includes a regression test, bz10078.exp.

I believe that this kludge causes a problem only in the following scenario:
- Function A calls setjmp and then calls B; and
- B or one of its callees calls longjmp; and
- A's stack frame contains no local variables or saved registers (including
%ebp), and B's stack frame contains no args.  I.e., there's nothing between the
return addresses in the two stack frames.
In such a scenario, we wouldn't detect that B has been bypassed by the longjmp.

I'm marking this fixed.  Reopen if it turns out we need a more sophisticated fix.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


http://sourceware.org/bugzilla/show_bug.cgi?id=10078

------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-04-21  0:07 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-16 23:15 [Bug uprobes/10078] New: uretprobes: longjmp fix broke funcs returning structs jkenisto at us dot ibm dot com
2009-04-21  0:07 ` [Bug uprobes/10078] " jkenisto at us dot ibm dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).