https://bugs.kde.org/show_bug.cgi?id=384681

            Bug ID: 384681
           Summary: PUT(pc, <variable>) should specialize to help
                    debugging
           Product: valgrind
           Version: 3.13 SVN
          Platform: Compiled Sources
                OS: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: NOR
         Component: memcheck
          Assignee: jsew...@acm.org
          Reporter: jrei...@bitwagon.com
  Target Milestone: ---

The VEX code for PUT(pc, <variable>) should specialize these cases in order to
help debugging:
  1) return from subroutine
  2) multi-way branch inside a subroutine (C-language 'switch')
  3) subroutine call indirect through a pointer-to-function
  4) any other write to pc of a non-constant value.  [There is no change for
PUT(pc, <constant>).]

Just allocate 4 more pseudo-registers in the thread state, and assign the
**current** pc (not the destination) to the appropriate slot.  And check that
the value is sane: not zero in any case, and if extra debugging is requested
then the destination should be mapped and executable, etc.  The emulator
doesn't have to be as dumb as the hardware.  Instead, the emulator can tell you
exactly where the problem was triggered.

Here's an example of how this is helpful.
===== stomp.S for ARM(32-bit)
_start: .globl _start  // execution starts here
        mov r0,#0  // value to overwrite return address
        bl sub  // call subroutine
        mov r7,#248  // NR_exit
        svc #0

sub:  // IN: r0: value to clobber pc
        stmdb sp!,{lr}  // save return address
        str r0,[sp]  // clobber the return address
        ldmia sp!,{pc}  // try to return
=====
  $ gcc -o stomp -nostartfiles -nostdlib stomp.S
  $ valgrind ./stomp
==19579== Memcheck, a memory error detector
==19579== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==19579== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==19579== Command: ./stomp
==19579== 
==19579== Jump to the invalid address stated on the next line
==19579==    at 0x0: ???
==19579==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==19579== 
==== SB 1 (evchecks 1) [tid 1] 0x0 UNKNOWN_FUNCTION UNKNOWN_OBJECT+0x0
==19579== 
==19579== Process terminating with default action of signal 11 (SIGSEGV):
dumping core
==19579==  Bad permissions for mapped region at address 0x0
==19579==    at 0x0: ???
==19579== 
==19579== HEAP SUMMARY:
==19579==     in use at exit: 0 bytes in 0 blocks
==19579==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==19579== 
==19579== All heap blocks were freed -- no leaks are possible
==19579== 
==19579== For counts of detected and suppressed errors, rerun with: -v
==19579== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
  $ 
=====

All that output, but no useful information: no hint of the pc just before it
became 0.  Instead, VEX should recognize "ldmia sp!,{pc}" as
return-from-subroutine, and save the address of the ldmia in the new
pseduo-register for "address of most recent RETURN".  Then when extra debugging
is requested a helper can check the new value of pc; and in any case the error
diagnostic for "bad pc" can print the most recent locations that wrote a
variable value into pc.  This can save hours of debugging time.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to