Message ID | 20170314100838.12647-2-roman.penyaev@profitbricks.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 14/03/2017 11:08, Roman Pen wrote: > For sure under corefile debugging it is not possible to invoke > any syscalls, like arch_prctl(), so avoid doing that. That will > simplify the script. Is the issue that start_thread only works in the main thread stack (i.e. not on coroutines)? > + num = gdb.selected_thread().num > + thr = gdb.execute('info thread %d' % num, to_string=True) What versions of gdb support gdb.execute? Also, what happens if localization is in effect? Paolo > + thr = thr.split('\n')[1] > try: > - return f.read_var("arg") > - except ValueError: > - return get_fs_base() > + return re.search('Thread ([0-9a-zx]+)', thr).group(1) > + except: > + raise ValueError("Unable to find pthread address in 'info thread %d' output.\n" > + "Probably version mismatch of libthread_db.so library?" % > + num)
On Tue, Mar 14, 2017 at 11:21 AM, Paolo Bonzini <pbonzini@redhat.com> wrote: > > > On 14/03/2017 11:08, Roman Pen wrote: >> For sure under corefile debugging it is not possible to invoke >> any syscalls, like arch_prctl(), so avoid doing that. That will >> simplify the script. > > Is the issue that start_thread only works in the main thread stack (i.e. > not on coroutines)? In my case I simply do not have libc6-dbg around. And yes, what you've mentioned is also the issue. > >> + num = gdb.selected_thread().num >> + thr = gdb.execute('info thread %d' % num, to_string=True) > > What versions of gdb support gdb.execute? Seems the beginning of python support in gdb (starting from gdb-7, right?). At least git blame shows me this modification date on particular function: d57a3c85f6eee (Thiago Jung Bauermann 2008-08-06 19:41:33 +0000 315) execute_gdb_command (PyObject *self, PyObject *args) and gdb-7 was released on October 06, 2009. > Also, what happens if localization is in effect? According to the gdb sources (I am not gdb developer, but this is quite straightforward to find) this is not the issue. What is the issue is that different targets output different lines. Linux is always the same, no worries, take a look gdb/linux-thread-db.c: thread_db_pid_to_str(): snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)", but e.g. bsd output should be different: gdb/bsd-uthread.c: bsd_uthread_pid_to_str(): xsnprintf (buf, sizeof buf, "process %d, thread 0x%lx", If this is the issue I can add third variant of getting correct pthread_self() and make the priority: 1. parse 'info thread' 2. parse 'start_thread(arg=XXX)' 3. go to arch_prctl() invocation. But frankly this is far from simplification, from what I've started :) -- Roman
On 14/03/2017 12:00, Roman Penyaev wrote: > Linux is always the same, no worries, take a look > > gdb/linux-thread-db.c: thread_db_pid_to_str(): > snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)", > > but e.g. bsd output should be different: > > gdb/bsd-uthread.c: bsd_uthread_pid_to_str(): > xsnprintf (buf, sizeof buf, "process %d, thread 0x%lx", > > If this is the issue I can add third variant of getting correct > pthread_self() and make the priority: > > 1. parse 'info thread' > 2. parse 'start_thread(arg=XXX)' > 3. go to arch_prctl() invocation. > > But frankly this is far from simplification, from what I've started :) I think it's okay. Absence of libc debugging symbols is not an issue, but the existing code was Linux-specific anyway and your version has some advantages for robustness. Paolo
diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py index ab699794abf6..1cfe3cd97e80 100644 --- a/scripts/qemugdb/coroutine.py +++ b/scripts/qemugdb/coroutine.py @@ -14,31 +14,22 @@ # GNU GPL, version 2 or (at your option) any later version. import gdb +import re VOID_PTR = gdb.lookup_type('void').pointer() -def get_fs_base(): - '''Fetch %fs base value using arch_prctl(ARCH_GET_FS). This is - pthread_self().''' - # %rsp - 120 is scratch space according to the SystemV ABI - old = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)') - gdb.execute('call arch_prctl(0x1003, $rsp - 120)', False, True) - fs_base = gdb.parse_and_eval('*(uint64_t*)($rsp - 120)') - gdb.execute('set *(uint64_t*)($rsp - 120) = %s' % old, False, True) - return fs_base - def pthread_self(): - '''Fetch pthread_self() from the glibc start_thread function.''' - f = gdb.newest_frame() - while f.name() != 'start_thread': - f = f.older() - if f is None: - return get_fs_base() + '''Get pthread_self() from '(gdb) info thread $id' output''' + num = gdb.selected_thread().num + thr = gdb.execute('info thread %d' % num, to_string=True) + thr = thr.split('\n')[1] try: - return f.read_var("arg") - except ValueError: - return get_fs_base() + return re.search('Thread ([0-9a-zx]+)', thr).group(1) + except: + raise ValueError("Unable to find pthread address in 'info thread %d' output.\n" + "Probably version mismatch of libthread_db.so library?" % + num) def get_glibc_pointer_guard(): '''Fetch glibc pointer guard value'''
This is a first step towards coroutines debugging using corefiles. It is much simpler to follow single path and always parse the line * 1 Thread 0x7f4475e33700 (LWP 7806) ^^^^^^^^^^^^^^ of a '(gdb) thread info $id' and get pthread pointer instead of rely on libc debugging information, which is not always the case. For sure under corefile debugging it is not possible to invoke any syscalls, like arch_prctl(), so avoid doing that. That will simplify the script. The other problem which is left unsolved for coroutines debugging using corefiles is gdb restriction to modify registers (that is only possible for live process, not for a corefile). This problem is solved in the next patch for a gdb project itself. Signed-off-by: Roman Pen <roman.penyaev@profitbricks.com> Cc: Stefan Hajnoczi <stefanha@redhat.com Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: qemu-devel@nongnu.org --- scripts/qemugdb/coroutine.py | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-)