From: Bart Van Assche Date: Mon, 7 Jul 2008 17:27:48 +0000 (+0000) Subject: Added intercepts for the public member functions of the Qt4 QMutex class. X-Git-Tag: svn/VALGRIND_3_4_0~355 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6036e0a75ce3eea40c458ada8dc0f20264a401b6;p=thirdparty%2Fvalgrind.git Added intercepts for the public member functions of the Qt4 QMutex class. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8383 --- diff --git a/drd/Makefile.am b/drd/Makefile.am index ca57d0c405..3a84697a93 100644 --- a/drd/Makefile.am +++ b/drd/Makefile.am @@ -2,7 +2,7 @@ include $(top_srcdir)/Makefile.tool.am noinst_PROGRAMS = if VGP_X86_LINUX - noinst_PROGRAMS += drd-x86-linux vgpreload_drd-x86-linux.so + noinst_PROGRAMS += drd-x86-linux vgpreload_drd-x86-linux.so endif if VGP_AMD64_LINUX noinst_PROGRAMS += drd-amd64-linux vgpreload_drd-amd64-linux.so @@ -14,17 +14,22 @@ if VGP_PPC64_LINUX noinst_PROGRAMS += drd-ppc64-linux vgpreload_drd-ppc64-linux.so endif if VGP_PPC32_AIX5 - noinst_PROGRAMS += drd-ppc32-aix5 vgpreload_drd-ppc32-aix5.so + noinst_PROGRAMS += drd-ppc32-aix5 vgpreload_drd-ppc32-aix5.so endif if VGP_PPC64_AIX5 - noinst_PROGRAMS += drd-ppc64-aix5 vgpreload_drd-ppc64-aix5.so + noinst_PROGRAMS += drd-ppc64-aix5 vgpreload_drd-ppc64-aix5.so +endif + + +VGPRELOAD_DRD_SOURCES = drd_strmem_intercepts.c drd_pthread_intercepts.c \ + $(VGPRELOAD_DRD_SOURCES_QT4) $(VGPRELOAD_DRD_SOURCES_OPENMP) + +if HAVE_QTCORE +VGPRELOAD_DRD_SOURCES += drd_qtcore_intercepts.c endif if HAVE_OPENMP -VGPRELOAD_DRD_SOURCES_COMMON = \ - drd_strmem_intercepts.c drd_pthread_intercepts.c drd_gomp_intercepts.c -else -VGPRELOAD_DRD_SOURCES_COMMON = drd_strmem_intercepts.c drd_pthread_intercepts.c +VGPRELOAD_DRD_SOURCES += drd_gomp_intercepts.c endif DRD_CFLAGS=@FLAG_W_EXTRA@ @FLAG_UNLIMITED_INLINE_UNIT_GROWTH@ \ @@ -38,7 +43,7 @@ AM_CFLAGS_PPC64_LINUX += $(DRD_CFLAGS) AM_CFLAGS_PPC32_AIX5 += $(DRD_CFLAGS) AM_CFLAGS_PPC64_AIX5 += $(DRD_CFLAGS) -vgpreload_drd_x86_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES_COMMON) +vgpreload_drd_x86_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES) vgpreload_drd_x86_linux_so_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX) vgpreload_drd_x86_linux_so_CFLAGS = $(AM_CFLAGS_X86_LINUX) $(AM_CFLAGS_PIC) vgpreload_drd_x86_linux_so_CCASFLAGS = $(AM_CCASFLAGS_X86_LINUX) @@ -46,7 +51,7 @@ vgpreload_drd_x86_linux_so_DEPENDENCIES = $(LIBREPLACEMALLOC_X86_LINUX) vgpreload_drd_x86_linux_so_LDFLAGS = $(PRELOAD_LDFLAGS_X86_LINUX)\ $(LIBREPLACEMALLOC_LDFLAGS_X86_LINUX) -vgpreload_drd_amd64_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES_COMMON) +vgpreload_drd_amd64_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES) vgpreload_drd_amd64_linux_so_CPPFLAGS = $(AM_CPPFLAGS_AMD64_LINUX) vgpreload_drd_amd64_linux_so_CFLAGS = $(AM_CFLAGS_AMD64_LINUX) $(AM_CFLAGS_PIC) vgpreload_drd_amd64_linux_so_CCASFLAGS = $(AM_CCASFLAGS_AMD64_LINUX) @@ -54,7 +59,7 @@ vgpreload_drd_amd64_linux_so_DEPENDENCIES = vgpreload_drd_amd64_linux_so_LDFLAGS = $(PRELOAD_LDFLAGS_AMD64_LINUX)\ $(LIBREPLACEMALLOC_LDFLAGS_AMD64_LINUX) -vgpreload_drd_ppc32_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES_COMMON) +vgpreload_drd_ppc32_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES) vgpreload_drd_ppc32_linux_so_CPPFLAGS = $(AM_CPPFLAGS_PPC32_LINUX) vgpreload_drd_ppc32_linux_so_CFLAGS = $(AM_CFLAGS_PPC32_LINUX) $(AM_CFLAGS_PIC) vgpreload_drd_ppc32_linux_so_CCASFLAGS = $(AM_CCASFLAGS_PPC32_LINUX) @@ -62,7 +67,7 @@ vgpreload_drd_ppc32_linux_so_DEPENDENCIES = vgpreload_drd_ppc32_linux_so_LDFLAGS = $(PRELOAD_LDFLAGS_PPC32_LINUX)\ $(LIBREPLACEMALLOC_LDFLAGS_PPC32_LINUX) -vgpreload_drd_ppc64_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES_COMMON) +vgpreload_drd_ppc64_linux_so_SOURCES = $(VGPRELOAD_DRD_SOURCES) vgpreload_drd_ppc64_linux_so_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX) vgpreload_drd_ppc64_linux_so_CFLAGS = $(AM_CFLAGS_PPC64_LINUX) $(AM_CFLAGS_PIC) vgpreload_drd_ppc64_linux_so_CCASFLAGS = $(AM_CCASFLAGS_PPC64_LINUX) @@ -70,7 +75,7 @@ vgpreload_drd_ppc64_linux_so_DEPENDENCIES = vgpreload_drd_ppc64_linux_so_LDFLAGS = $(PRELOAD_LDFLAGS_PPC64_LINUX)\ $(LIBREPLACEMALLOC_LDFLAGS_PPC64_LINUX) -vgpreload_drd_ppc32_aix5_so_SOURCES = $(VGPRELOAD_DRD_SOURCES_COMMON) +vgpreload_drd_ppc32_aix5_so_SOURCES = $(VGPRELOAD_DRD_SOURCES) vgpreload_drd_ppc32_aix5_so_CPPFLAGS = $(AM_CPPFLAGS_PPC32_AIX5) vgpreload_drd_ppc32_aix5_so_CFLAGS = $(AM_CFLAGS_PPC32_AIX5) $(AM_CFLAGS_PIC) vgpreload_drd_ppc32_aix5_so_CCASFLAGS = $(AM_CCASFLAGS_PPC32_AIX5) @@ -78,7 +83,7 @@ vgpreload_drd_ppc32_aix5_so_DEPENDENCIES = vgpreload_drd_ppc32_aix5_so_LDFLAGS = $(PRELOAD_LDFLAGS_PPC32_AIX5)\ $(LIBREPLACEMALLOC_LDFLAGS_PPC32_AIX5) -vgpreload_drd_ppc64_aix5_so_SOURCES = $(VGPRELOAD_DRD_SOURCES_COMMON) +vgpreload_drd_ppc64_aix5_so_SOURCES = $(VGPRELOAD_DRD_SOURCES) vgpreload_drd_ppc64_aix5_so_CPPFLAGS = $(AM_CPPFLAGS_PPC64_AIX5) vgpreload_drd_ppc64_aix5_so_CFLAGS = $(AM_CFLAGS_PPC64_AIX5) $(AM_CFLAGS_PIC) vgpreload_drd_ppc64_aix5_so_CCASFLAGS = $(AM_CCASFLAGS_PPC64_AIX5) @@ -87,7 +92,7 @@ vgpreload_drd_ppc64_aix5_so_LDFLAGS = $(PRELOAD_LDFLAGS_PPC64_AIX5)\ $(LIBREPLACEMALLOC_LDFLAGS_PPC64_AIX5) -DRD_SOURCES_COMMON = \ +DRD_SOURCES = \ drd_barrier.c \ drd_clientobj.c \ drd_clientreq.c \ @@ -122,42 +127,42 @@ noinst_HEADERS = \ drd_vc.h \ pub_drd_bitmap.h -drd_x86_linux_SOURCES = $(DRD_SOURCES_COMMON) +drd_x86_linux_SOURCES = $(DRD_SOURCES) drd_x86_linux_CPPFLAGS = $(AM_CPPFLAGS_X86_LINUX) drd_x86_linux_CFLAGS = $(AM_CFLAGS_X86_LINUX) drd_x86_linux_DEPENDENCIES = $(COREGRIND_LIBS_X86_LINUX) drd_x86_linux_LDADD = $(TOOL_LDADD_X86_LINUX) drd_x86_linux_LDFLAGS = $(TOOL_LDFLAGS_X86_LINUX) -drd_amd64_linux_SOURCES = $(DRD_SOURCES_COMMON) +drd_amd64_linux_SOURCES = $(DRD_SOURCES) drd_amd64_linux_CPPFLAGS = $(AM_CPPFLAGS_AMD64_LINUX) drd_amd64_linux_CFLAGS = $(AM_CFLAGS_AMD64_LINUX) drd_amd64_linux_DEPENDENCIES = $(COREGRIND_LIBS_AMD64_LINUX) drd_amd64_linux_LDADD = $(TOOL_LDADD_AMD64_LINUX) drd_amd64_linux_LDFLAGS = $(TOOL_LDFLAGS_AMD64_LINUX) -drd_ppc32_linux_SOURCES = $(DRD_SOURCES_COMMON) +drd_ppc32_linux_SOURCES = $(DRD_SOURCES) drd_ppc32_linux_CPPFLAGS = $(AM_CPPFLAGS_PPC32_LINUX) drd_ppc32_linux_CFLAGS = $(AM_CFLAGS_PPC32_LINUX) drd_ppc32_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_LINUX) drd_ppc32_linux_LDADD = $(TOOL_LDADD_PPC32_LINUX) drd_ppc32_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC32_LINUX) -drd_ppc64_linux_SOURCES = $(DRD_SOURCES_COMMON) +drd_ppc64_linux_SOURCES = $(DRD_SOURCES) drd_ppc64_linux_CPPFLAGS = $(AM_CPPFLAGS_PPC64_LINUX) drd_ppc64_linux_CFLAGS = $(AM_CFLAGS_PPC64_LINUX) drd_ppc64_linux_DEPENDENCIES = $(COREGRIND_LIBS_PPC64_LINUX) drd_ppc64_linux_LDADD = $(TOOL_LDADD_PPC64_LINUX) drd_ppc64_linux_LDFLAGS = $(TOOL_LDFLAGS_PPC64_LINUX) -drd_ppc32_aix5_SOURCES = $(DRD_SOURCES_COMMON) +drd_ppc32_aix5_SOURCES = $(DRD_SOURCES) drd_ppc32_aix5_CPPFLAGS = $(AM_CPPFLAGS_PPC32_AIX5) drd_ppc32_aix5_CFLAGS = $(AM_CFLAGS_PPC32_AIX5) drd_ppc32_aix5_DEPENDENCIES = $(COREGRIND_LIBS_PPC32_AIX5) drd_ppc32_aix5_LDADD = $(TOOL_LDADD_PPC32_AIX5) drd_ppc32_aix5_LDFLAGS = $(TOOL_LDFLAGS_PPC32_AIX5) -drd_ppc64_aix5_SOURCES = $(DRD_SOURCES_COMMON) +drd_ppc64_aix5_SOURCES = $(DRD_SOURCES) drd_ppc64_aix5_CPPFLAGS = $(AM_CPPFLAGS_PPC64_AIX5) drd_ppc64_aix5_CFLAGS = $(AM_CFLAGS_PPC64_AIX5) drd_ppc64_aix5_DEPENDENCIES = $(COREGRIND_LIBS_PPC64_AIX5) diff --git a/drd/drd_qtcore_intercepts.c b/drd/drd_qtcore_intercepts.c new file mode 100644 index 0000000000..763e3112f8 --- /dev/null +++ b/drd/drd_qtcore_intercepts.c @@ -0,0 +1,204 @@ + +/*--------------------------------------------------------------------*/ +/*--- Client-space code for drd. drd_qtcore_intercepts.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of drd, a data race detector. + + Copyright (C) 2006-2008 Bart Van Assche + bart.vanassche@gmail.com + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. +*/ + +/* --------------------------------------------------------------------- + ALL THE CODE IN THIS FILE RUNS ON THE SIMULATED CPU. + + These functions are not called directly - they're the targets of code + redirection or load notifications (see pub_core_redir.h for info). + They're named weirdly so that the intercept code can find them when the + shared object is initially loaded. + + Note that this filename has the "drd_" prefix because it can appear + in stack traces, and the "drd_" makes it a little clearer that it + originates from Valgrind. + ------------------------------------------------------------------ */ + +#include +#include "drd_clientreq.h" +#include "pub_tool_redir.h" + + +// Defines. + +#define QT4CORE_FUNC(ret_ty, f, args...) \ + ret_ty VG_WRAP_FUNCTION_ZU(libQtCoreZdsoZd4,f)(args); \ + ret_ty VG_WRAP_FUNCTION_ZU(libQtCoreZdsoZd4,f)(args) + + + +////////////////////////////////////////////////////////////////// +// QMutex intercepts. +////////////////////////////////////////////////////////////////// + + +typedef enum { qt_nonrecursive = 0, qt_recursive = 1 } qt_mutex_mode; + + +/** Convert a Qt4 mutex type to a DRD mutex type. */ +static MutexT qt_to_drd_mutex_type(qt_mutex_mode mode) +{ + switch (mode) + { + case qt_nonrecursive: + return mutex_type_default_mutex; + case qt_recursive: + return mutex_type_recursive_mutex; + } + return mutex_type_invalid_mutex; +} + +/** Find out the type of a Qt4 mutex (recursive or not). + * Since it's not possible to do this in a portable way, return + * mutex_type_unknown and let drd_mutex.c look up the real mutex type. + */ +static MutexT mutex_type(void* qt4_mutex) +{ + return mutex_type_unknown; +} + + +// QMutex::QMutex(RecursionMode) -- _ZN6QMutexC1ENS_13RecursionModeE, +QT4CORE_FUNC(void, _ZN6QMutexC1ENS_13RecursionModeE, + void* mutex, + qt_mutex_mode mode) +{ + int ret; + int res; + OrigFn fn; + VALGRIND_GET_ORIG_FN(fn); + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT, + mutex, qt_to_drd_mutex_type(mode), 0, 0, 0); + CALL_FN_W_WW(ret, fn, mutex, mode); + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT, + mutex, 0, 0, 0, 0); +} + +// QMutex::QMutex(RecursionMode) -- _ZN6QMutexC2ENS_13RecursionModeE +QT4CORE_FUNC(void, _ZN6QMutexC2ENS_13RecursionModeE, + void* mutex, + qt_mutex_mode mode) +{ + int ret; + int res; + OrigFn fn; + VALGRIND_GET_ORIG_FN(fn); + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_INIT, + mutex, qt_to_drd_mutex_type(mode), 0, 0, 0); + CALL_FN_W_WW(ret, fn, mutex, mode); + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT, + mutex, 0, 0, 0, 0); +} + +// QMutex::~QMutex() -- _ZN6QMutexD1Ev +QT4CORE_FUNC(void, _ZN6QMutexD1Ev, + void* mutex) +{ + int ret; + int res; + OrigFn fn; + VALGRIND_GET_ORIG_FN(fn); + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY, + mutex, 0, 0, 0, 0); + CALL_FN_W_W(ret, fn, mutex); + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY, + mutex, mutex_type(mutex), 0, 0, 0); +} + +// QMutex::~QMutex() -- _ZN6QMutexD2Ev +QT4CORE_FUNC(void, _ZN6QMutexD2Ev, + void** mutex) +{ + int ret; + int res; + OrigFn fn; + VALGRIND_GET_ORIG_FN(fn); + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY, + mutex, 0, 0, 0, 0); + CALL_FN_W_W(ret, fn, mutex); + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_DESTROY, + mutex, mutex_type(mutex), 0, 0, 0); +} + +// QMutex::lock() -- _ZN6QMutex4lockEv +QT4CORE_FUNC(void, _ZN6QMutex4lockEv, + void* mutex) +{ + int ret; + int res; + OrigFn fn; + VALGRIND_GET_ORIG_FN(fn); + VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK, + mutex, mutex_type(mutex), 0, 0, 0); + CALL_FN_W_W(ret, fn, mutex); + VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__POST_MUTEX_LOCK, + mutex, 1, 0, 0, 0); +} + +// QMutex::tryLock() -- _ZN6QMutex7tryLockEv +QT4CORE_FUNC(int, _ZN6QMutex7tryLockEv, + void* mutex) +{ + int ret; + int res; + OrigFn fn; + VALGRIND_GET_ORIG_FN(fn); + VALGRIND_DO_CLIENT_REQUEST(res, 0, VG_USERREQ__PRE_MUTEX_LOCK, + mutex, mutex_type(mutex), 1, 0, 0); + CALL_FN_W_W(ret, fn, mutex); + VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_LOCK, + mutex, ret, 0, 0, 0); + return ret; +} + +// QMutex::tryLock(int) -- _ZN6QMutex7tryLockEi +QT4CORE_FUNC(int, _ZN6QMutex7tryLockEi, + void* mutex, + int timeout) +{ + // Not yet implemented. + assert(0); +} + +// QMutex::unlock() -- _ZN6QMutex6unlockEv +QT4CORE_FUNC(void, _ZN6QMutex6unlockEv, + void* mutex) +{ + int ret; + int res; + OrigFn fn; + VALGRIND_GET_ORIG_FN(fn); + VALGRIND_DO_CLIENT_REQUEST(res, -1, + VG_USERREQ__PRE_MUTEX_UNLOCK, + mutex, mutex_type(mutex), 0, 0, 0); + CALL_FN_W_W(ret, fn, mutex); + VALGRIND_DO_CLIENT_REQUEST(res, -1, + VG_USERREQ__POST_MUTEX_UNLOCK, + mutex, 0, 0, 0, 0); +}