From: Philippe Waroquiers Date: Sat, 21 Dec 2013 16:57:26 +0000 (+0000) Subject: Fix drd assert failure for monitor cmd execution when all threads blocked in syscall X-Git-Tag: svn/VALGRIND_3_10_0~671 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=af36bdd9afdfacd50fd340150663d9dd67d16556;p=thirdparty%2Fvalgrind.git Fix drd assert failure for monitor cmd execution when all threads blocked in syscall 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 --- diff --git a/drd/drd_clientreq.c b/drd/drd_clientreq.c index 22e0b59fd2..6d6791641f 100644 --- a/drd/drd_clientreq.c +++ b/drd/drd_clientreq.c @@ -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]) {