qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/1] scripts/qemugdb/coroutine.py: get pthread point


From: Roman Pen
Subject: [Qemu-devel] [PATCH 1/1] scripts/qemugdb/coroutine.py: get pthread pointer from '(gdb) thread info $id' output
Date: Tue, 14 Mar 2017 11:08:38 +0100

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 <address@hidden>
Cc: Stefan Hajnoczi <address@hidden
Cc: Paolo Bonzini <address@hidden>
Cc: address@hidden
---
 scripts/qemugdb/coroutine.py | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)

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'''
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]