Public bug reported: While running qemu user x86_64 x86 with gdb server, calling functions are not working.
Here is how to reproduce it: run in a terminal: $ qemu-x86_64 -g 12345 -L / /bin/ls In another terminal run gdb: (gdb) file /bin/ls (gdb) target remote :12345 (gdb) b _init (gdb) c (gdb) call malloc(1) Could not fetch register "fs_base"; remote failure reply 'E14' In other cases we also got the error: Could not fetch register "orig_rax"; remote failure reply 'E14' Here is how I patched it (it is only a workaround): diff --git a/gdbstub.c b/gdbstub.c index 2a94030..5749efe 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -668,6 +668,11 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) return r->get_reg(env, mem_buf, reg - r->base_reg); } } +#ifdef TARGET_X86_64 + return 8; +#elif TARGET_I386 + return 4; +#endif return 0; } (Our guess for this issue was, gdb is requesting for 'fake' registers to know register size) Once we patched that, we got another problem while calling functions from gdb: We could call functions, but only once. Here is how to reproduce it: run in a terminal: $ qemu-x86_64 -g 12345 -L / /bin/ls In another terminal run gdb: (gdb) file /bin/ls (gdb) target remote :12345 (gdb) b _init (gdb) c (gdb) call malloc(1) $1 = (void *) 0x620010 (gdb) call malloc(1) Cannot access memory at address 0x40007ffb8f Here is how we patched it to make it work: diff --git a/exec.c b/exec.c index 03238a3..d303922 100644 --- a/exec.c +++ b/exec.c @@ -2833,7 +2833,7 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, if (!(flags & PAGE_VALID)) return -1; if (is_write) { - if (!(flags & PAGE_WRITE)) + if (!(flags & (PAGE_WRITE | PAGE_WRITE_ORG))) return -1; /* XXX: this code should not depend on lock_user */ if (!(p = lock_user(VERIFY_WRITE, addr, l, 0))) >From what we saw, there is a page which is passed to read-only after first execution, and gdb need to write on that page to put a breakpoint. (on the stack to get function return) We suspect this is linked to this: https://qemu.weilnetz.de/w64/2012/2012-06-28/qemu-tech.html#Self_002dmodifying-code-and-translated-code-invalidation ** Affects: qemu Importance: Undecided Status: New ** Summary changed: - qemu-user x86_64 x86 gdb call function not working properly + qemu-user x86_64 x86 gdb call function from gdb doesn't work ** Description changed: While running qemu user x86_64 x86 with gdb server, calling functions are not working. Here is how to reproduce it: run in a terminal: $ qemu-x86_64 -g 12345 -L / /bin/ls In another terminal run gdb: (gdb) file /bin/ls (gdb) target remote :12345 (gdb) b _init (gdb) c (gdb) call malloc(1) Could not fetch register "fs_base"; remote failure reply 'E14' In other cases we also got the error: Could not fetch register "orig_rax"; remote failure reply 'E14' Here is how I patched it (it is only a workaround): diff --git a/gdbstub.c b/gdbstub.c index 2a94030..5749efe 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -668,6 +668,11 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) - return r->get_reg(env, mem_buf, reg - r->base_reg); - } - } + return r->get_reg(env, mem_buf, reg - r->base_reg); + } + } +#ifdef TARGET_X86_64 + return 8; +#elif TARGET_I386 + return 4; +#endif - return 0; - } + return 0; + } (Our guess for this issue was, gdb is requesting for 'fake' registers to know register size) Once we patched that, we got another problem while calling functions from gdb: We could call functions, but only once. Here is how to reproduce it: run in a terminal: $ qemu-x86_64 -g 12345 -L / /bin/ls In another terminal run gdb: (gdb) file /bin/ls (gdb) target remote :12345 (gdb) b _init (gdb) c (gdb) call malloc(1) $1 = (void *) 0x620010 (gdb) call malloc(1) Cannot access memory at address 0x40007ffb8f Here is how we patched it to make it work: diff --git a/exec.c b/exec.c index 03238a3..d303922 100644 --- a/exec.c +++ b/exec.c @@ -2833,7 +2833,7 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, - if (!(flags & PAGE_VALID)) - return -1; - if (is_write) { + if (!(flags & PAGE_VALID)) + return -1; + if (is_write) { - if (!(flags & PAGE_WRITE)) + if (!(flags & (PAGE_WRITE | 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; + /* XXX: this code should not depend on lock_user */ + if (!(p = lock_user(VERIFY_WRITE, addr, l, 0))) From what we saw, there is a page which is passed to read-only after first execution, and gdb need to write on that page to put a breakpoint. - (on the stack) + (on the stack to get function return) We suspect this is linked to this: https://qemu.weilnetz.de/w64/2012/2012-06-28/qemu-tech.html#Self_002dmodifying-code-and-translated-code-invalidation -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1774149 Title: qemu-user x86_64 x86 gdb call function from gdb doesn't work Status in QEMU: New Bug description: While running qemu user x86_64 x86 with gdb server, calling functions are not working. Here is how to reproduce it: run in a terminal: $ qemu-x86_64 -g 12345 -L / /bin/ls In another terminal run gdb: (gdb) file /bin/ls (gdb) target remote :12345 (gdb) b _init (gdb) c (gdb) call malloc(1) Could not fetch register "fs_base"; remote failure reply 'E14' In other cases we also got the error: Could not fetch register "orig_rax"; remote failure reply 'E14' Here is how I patched it (it is only a workaround): diff --git a/gdbstub.c b/gdbstub.c index 2a94030..5749efe 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -668,6 +668,11 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) return r->get_reg(env, mem_buf, reg - r->base_reg); } } +#ifdef TARGET_X86_64 + return 8; +#elif TARGET_I386 + return 4; +#endif return 0; } (Our guess for this issue was, gdb is requesting for 'fake' registers to know register size) Once we patched that, we got another problem while calling functions from gdb: We could call functions, but only once. Here is how to reproduce it: run in a terminal: $ qemu-x86_64 -g 12345 -L / /bin/ls In another terminal run gdb: (gdb) file /bin/ls (gdb) target remote :12345 (gdb) b _init (gdb) c (gdb) call malloc(1) $1 = (void *) 0x620010 (gdb) call malloc(1) Cannot access memory at address 0x40007ffb8f Here is how we patched it to make it work: diff --git a/exec.c b/exec.c index 03238a3..d303922 100644 --- a/exec.c +++ b/exec.c @@ -2833,7 +2833,7 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, if (!(flags & PAGE_VALID)) return -1; if (is_write) { - if (!(flags & PAGE_WRITE)) + if (!(flags & (PAGE_WRITE | PAGE_WRITE_ORG))) return -1; /* XXX: this code should not depend on lock_user */ if (!(p = lock_user(VERIFY_WRITE, addr, l, 0))) From what we saw, there is a page which is passed to read-only after first execution, and gdb need to write on that page to put a breakpoint. (on the stack to get function return) We suspect this is linked to this: https://qemu.weilnetz.de/w64/2012/2012-06-28/qemu-tech.html#Self_002dmodifying-code-and-translated-code-invalidation To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1774149/+subscriptions