]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix drd assert failure for monitor cmd execution when all threads blocked in syscall
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 21 Dec 2013 16:57:26 +0000 (16:57 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Sat, 21 Dec 2013 16:57:26 +0000 (16:57 +0000)
When all threads are blocked in a syscall, DRD_(thread_get_running_tid)()
returns (or can return?) a "valid" DrdThreadId (probably the last one
that was running ?).
However, in such a situation, VG_(get_running_tid)() returns 0 (as effectively
there is no thread running).

This discrepancy (drd_tid "valid" and "vg_tid" invalid) can (probably) only
happen with gdb monitor commands, as a thread can (normally) execute a
client request only when it is running.

However, vgdb can "force" the invocation of the gdb monitor client request,
even if no thread is running.
In such a case, the assert should not verify that drd_tid and vg_tid are
consistent.

To reproduce the problem:
  ./vg-in-place --tool=drd sleep 60
and in another window:
  ./coregrind/vgdb help
which then gives
  ...
  drd: drd_clientreq.c:84 (handle_client_request): Assertion 'DRD_(VgThreadIdToDrdThreadId)(vg_tid) == drd_tid' failed.
  ==4208==    at 0x3801DE1D: report_and_quit (m_libcassert.c:260)
  ==4208==    by 0x3801E034: vgPlain_assert_fail (m_libcassert.c:340)
  ==4208==    by 0x380026CC: handle_client_request (drd_clientreq.c:84)
  ==4208==    by 0x3806EE8F: handle_gdb_monitor_command (server.c:490)
  ==4208==    by 0x3806F07A: handle_query (server.c:580)
  ==4208==    by 0x3806FDB2: server_main (server.c:915)
  ==4208==    by 0x3806B01C: call_gdbserver (m_gdbserver.c:706)
  ==4208==    by 0x3806B8F2: vgPlain_invoke_gdbserver (m_gdbserver.c:892)
  ...

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13765

drd/drd_clientreq.c

index 22e0b59fd227f6a808bc87adfef9e3a7f577aa06..6d6791641f805d49d485d4f80cd5f3ba61786b68 100644 (file)
@@ -81,7 +81,16 @@ static Bool handle_client_request(ThreadId vg_tid, UWord* arg, UWord* ret)
    const DrdThreadId drd_tid = DRD_(thread_get_running_tid)();
 
    tl_assert(vg_tid == VG_(get_running_tid()));
-   tl_assert(DRD_(VgThreadIdToDrdThreadId)(vg_tid) == drd_tid);
+   tl_assert(DRD_(VgThreadIdToDrdThreadId)(vg_tid) == drd_tid
+             || (VG_USERREQ__GDB_MONITOR_COMMAND == arg[0]
+                 && vg_tid == VG_INVALID_THREADID));
+   /* Check the consistency of vg_tid and drd_tid, unless
+      vgdb has forced the invokation of a gdb monitor cmd
+      when no threads was running (i.e. all threads blocked
+      in a syscall. In such a case, vg_tid is invalid,
+      its conversion to a drd thread id gives also an invalid
+      drd thread id, but drd_tid is not invalid (probably
+      equal to the last running drd thread. */
 
    switch (arg[0])
    {