qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] GDB function call failing due to memory protection of stack page in QEMU
@ 2013-04-11 11:20 Abid, Hafiz
  2013-04-18  8:31 ` Abid, Hafiz
  2013-04-18  8:36 ` Peter Maydell
  0 siblings, 2 replies; 4+ messages in thread
From: Abid, Hafiz @ 2013-04-11 11:20 UTC (permalink / raw)
  To: qemu-devel; +Cc: gdb, riku.voipio, macro

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

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

* Re: [Qemu-devel] GDB function call failing due to memory protection of stack page in QEMU
  2013-04-11 11:20 [Qemu-devel] GDB function call failing due to memory protection of stack page in QEMU Abid, Hafiz
@ 2013-04-18  8:31 ` Abid, Hafiz
  2013-04-18  8:36 ` Peter Maydell
  1 sibling, 0 replies; 4+ messages in thread
From: Abid, Hafiz @ 2013-04-18  8:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: gdb, riku.voipio, macro

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

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

* Re: [Qemu-devel] GDB function call failing due to memory protection of stack page in QEMU
  2013-04-11 11:20 [Qemu-devel] GDB function call failing due to memory protection of stack page in QEMU Abid, Hafiz
  2013-04-18  8:31 ` Abid, Hafiz
@ 2013-04-18  8:36 ` Peter Maydell
  2013-04-18  9:28   ` Abid, Hafiz
  1 sibling, 1 reply; 4+ messages in thread
From: Peter Maydell @ 2013-04-18  8:36 UTC (permalink / raw)
  To: Abid, Hafiz; +Cc: gdb, riku.voipio, macro, qemu-devel

On 11 April 2013 12:20, Abid, Hafiz <hafiz_abid@mentor.com> 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.

My worry here is that this will mean that writes by the
debugger won't trigger the "code area has been written, QEMU
must throw away any cached translated code for that region"
check. This is a tricky area of the code...

thanks
-- PMM

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

* Re: [Qemu-devel] GDB function call failing due to memory protection of stack page in QEMU
  2013-04-18  8:36 ` Peter Maydell
@ 2013-04-18  9:28   ` Abid, Hafiz
  0 siblings, 0 replies; 4+ messages in thread
From: Abid, Hafiz @ 2013-04-18  9:28 UTC (permalink / raw)
  To: Peter Maydell; +Cc: gdb, riku.voipio, macro, qemu-devel

On 18/04/13 09:36:55, Peter Maydell wrote:
> > 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.
> 
> My worry here is that this will mean that writes by the
> debugger won't trigger the "code area has been written, QEMU
> must throw away any cached translated code for that region"
> check. This is a tricky area of the code...

Thanks for your comments. I have observed that in this case, code does  
end up calling
tb_invalidate_phys_page() which should invalidate the translated code.  
Please see the call
stack below.

Also the comments in the page_unprotect() and page_check_range() seem  
to suggest that code
was written with similar case in mind.

page_check_range()
     /* unprotect the page if it was put read-only because it
          contains translated code */
        if (!(p->flags & PAGE_WRITE)) {
                 if (!page_unprotect(addr, 0, NULL)) {
                    return -1;
                 }

page_unprotect()
     /* if the page was really writable, then we change its
        protection back to writable */
     if ((p->flags & PAGE_WRITE_ORG) && !(p->flags & PAGE_WRITE)) {

Having said that, I am open to other ideas to solve this problem. The  
2nd idea I have was to not add
write protection to a page if it meets certain condition as I described  
in my original email. Does that look
like a better solution to you?

tb_invalidate_phys_page() at translate-all.c:1,157 0x800d1321	
page_unprotect() at translate-all.c:1,811 0x800d1f8c	
page_check_range() at translate-all.c:1,768 0x800d20a9	
access_ok() at qemu.h:286 0x8002ab7c	
lock_user() at qemu.h:397 0x8002ab7c	
cpu_memory_rw_debug() at exec.c:1,851 0x8002ab7c	
target_memory_rw_debug() at gdbstub.c:49 0x8004610a	
gdb_handle_packet() at gdbstub.c:2,273 0x8004610a	
gdb_read_byte() at gdbstub.c:2,728 0x80046ef5	
page_unprotect() at translate-all.c:1,811 0x800d1f87	
page_check_range() at translate-all.c:1,768 0x800d20a9	
access_ok() at qemu.h:286 0x8002ab7c	
lock_user() at qemu.h:397 0x8002ab7c	
cpu_memory_rw_debug() at exec.c:1,851 0x8002ab7c	
target_memory_rw_debug() at gdbstub.c:49 0x8004610a	
gdb_handle_packet() at gdbstub.c:2,273 0x8004610a	
gdb_read_byte() at gdbstub.c:2,728 0x80046ef5	
gdb_handlesig() at gdbstub.c:2,812 0x80046ef5

Regards,
Abid


> 
> thanks
> -- PMM
> 


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

end of thread, other threads:[~2013-04-18  9:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-11 11:20 [Qemu-devel] GDB function call failing due to memory protection of stack page in QEMU Abid, Hafiz
2013-04-18  8:31 ` Abid, Hafiz
2013-04-18  8:36 ` Peter Maydell
2013-04-18  9:28   ` Abid, Hafiz

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 NNTP newsgroup(s).