GDB function call failing due to memory protection of stack page in QEMU

Abid, Hafiz hafiz_abid@mentor.com
Thu Apr 18 08:31:00 GMT 2013


ping.

On 11/04/13 12:20:57, Abid, Hafiz wrote:
> Hi All,
> I have faced a problem using GDB with user-mode qemu. Although  
> problem was observed for MIPS, I think it is a generic problem. I  
> would appreciate an advice from experts on how best to deal with.  
> Here is the problem description.
> 
> GDB has ability to call function from the program being debugged  
> (http://sourceware.org/gdb/onlinedocs/gdb/Calling.html#Calling). For  
> MIPS (and on other architectures), it put a breakpoint on the stack  
> that is used as return address of the function. When that breakpoint  
> is hit, GDB knows that function is complete and it can return control  
> to user. This breakpoint on stack causes problem for QEMU. When it  
> runs that instruction from stack, it add write-protection to that  
> page. So after the function call, GDB is not able to write to stack.  
> So any future function call or other operation that need to write to  
> stack will fail. I show an example session below taken mostly from  
> call-sc.exp of GDB testsuite.
> 
> There are 2 possible solution in my mind. One was to allow writing  
> memory if this page originally had write access. This is a single  
> line fix and a patch is below.
> 
> Second option was to not add write protection to the page in the  
> first place if
> i) Page currently has write access.
> ii) First instruction is a breakpoint.
> 
> If 2nd looks a better option then I can prepare a patch for it. If  
> there some other approach that will better solve this problem then  
> please let me know.
> 
> Thanks,
> Abid
> 
> GDB session:
> GNU gdb (GDB) 7.4.50.20120716-cvs
> Copyright (C) 2012 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later  
> <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.  Type "show  
> copying"
> and "show warranty" for details.
> This GDB was configured as "--host=i686-pc-linux-gnu  
> --target=mips-linux-gnu".
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>...
> Reading symbols from /home/abidh/work/mips-demo/call_static...done.
> (gdb) target remote :8000
> Remote debugging using :8000
> [New Remote target]
> [Switching to Remote target]
> __start () at ../ports/sysdeps/mips/start.S:84
> 84	../ports/sysdeps/mips/start.S: No such file or directory.
> (gdb) break main
> Breakpoint 1 at 0x4011e8: file call.c, line 63.
> (gdb) c
> Continuing.
> 
> Breakpoint 1, main () at call.c:63
> 63	  Fun(foo);	
> (gdb) p /c fun()
> $1 = 49 '1'
> (gdb) p /c fun()
> Cannot access memory at address 0x40800258
> (gdb)
> 
> Signed-off-by: Hafiz Abid Qadeer <hafiz_abid@mentor.com>
> ---
>  exec.c |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/exec.c b/exec.c
> index fa1e0c3..af5610b 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -1844,8 +1844,9 @@ int cpu_memory_rw_debug(CPUArchState *env,  
> target_ulong addr,
>          if (!(flags & PAGE_VALID))
>              return -1;
>          if (is_write) {
> -            if (!(flags & PAGE_WRITE))
> +            if ((!(flags & PAGE_WRITE)) && (!(flags &  
> PAGE_WRITE_ORG))) {
>                  return -1;
> +            }
>              /* XXX: this code should not depend on lock_user */
>              if (!(p = lock_user(VERIFY_WRITE, addr, l, 0)))
>                  return -1;
>-- 
> 1.7.9.5



More information about the Gdb mailing list