[Ltrace-devel] [PATCH] [MIPS] Detect return from rt_sigreturn syscalls

Eugene Rudoy gene at freetz.org
Wed Feb 18 23:57:23 UTC 2015


Hi Faraz,

hmm, I'm still having the same behavior as without the patch - a lot
of unexpected breakpoints at exactly the same places. S. attached
logs.

Best regards,
Gene

On Wed, Feb 18, 2015 at 12:36 AM, Faraz Shahbazker
<faraz.shahbazker at imgtec.com> wrote:
> On MIPS, rt_sigreturn does not return control to the instruction after
> the syscall instruction. Instead, it transfers control directly to
> the point where the signal occurred. If this transfer is not correctly
> marked as a SYSRET event, it gets mis-categorized as a breakpoint event
> and generates "unexpected breakpoint" messages. The rt_sigreturn
> frame remains on the callstack until the next rt_sigreturn, which is then
> misinterpreted as as a return from the previous 'unfinished' syscall.
>
> If the top of the callstack is a rt_sigreturn syscall, we must force
> the current event to be treated as a SYSRET without checking for a
> preceding SYSCALL instruction.
>
> Verify by invoking:
> $ ltrace [-S] openssl speed
> ---
>  sysdeps/linux-gnu/mips/trace.c |   13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/sysdeps/linux-gnu/mips/trace.c b/sysdeps/linux-gnu/mips/trace.c
> index 88e13ac..5651fa3 100644
> --- a/sysdeps/linux-gnu/mips/trace.c
> +++ b/sysdeps/linux-gnu/mips/trace.c
> @@ -30,6 +30,7 @@
>  #include <sys/ptrace.h>
>  #include <asm/ptrace.h>
>  #include <assert.h>
> +#include <asm/unistd.h>
>
>  #include "backend.h"
>  #include "common.h"
> @@ -103,7 +104,17 @@ syscall_p(struct process *proc, int status, int *sysnum)
>                    0000000c    syscall
>                  */
>                 if(insn!=0x0000000c){
> -                       return 0;
> +                       /* rt_sigreturn returns control to the point
> +                          where the signal was received; skip check
> +                          for preceeding syscall instruction */
> +                       int depth = proc->callstack_depth;
> +                       if (depth > 0 &&
> +                           proc->callstack[depth - 1].is_syscall &&
> +                           proc->callstack[depth - 1].c_un.syscall ==
> +                           (__NR_rt_sigreturn - __NR_Linux))
> +                               return 2;
> +                       else
> +                               return 0;
>                 }
>
>                 *sysnum = (num & 0xFFFF) - 4000;
> --
> 1.7.9.5
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: openssl_speed-20150218.log.gz
Type: application/x-gzip
Size: 6601 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/ltrace-devel/attachments/20150219/aca04d3b/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: openssl_speed_D1-20150218.log.gz
Type: application/x-gzip
Size: 15892 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/ltrace-devel/attachments/20150219/aca04d3b/attachment-0003.bin>


More information about the Ltrace-devel mailing list