paulfloyd / freebsd_valgrind

Git repo used to Upstream the FreeBSD Port of Valgrind
GNU General Public License v2.0
15 stars 4 forks source link

drd/tests/omp_printf is failing [FreeBSD 12.2 i386] #149

Closed paulfloyd closed 3 years ago

paulfloyd commented 3 years ago

drd: ./drd_bitmap.c:239 (void vgDrd_bm_access_range_store(struct bitmap *const, const Addr, const Addr)): Assertion 'a1 <= a2' failed. + +host stacktrace:

paulfloyd commented 3 years ago

And on amd64 this is also failing

+The object at address 0x........ is not a mutex.

paulfloyd commented 3 years ago

On amd64, with some gdb and dtrace, I see that there are 11 calls to pthread_mutex_init but 12 calls to pthread_mutex_destroy.

This is not necessarily a bad thing since a mutex can either be initialized by pthread_mutex_init() or by direct initialization

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

paulfloyd commented 3 years ago

I wrote a little dtrace script

#!/usr/sbin/dtrace -s

pid$target:libthr:pthread_mutex_init:entry  {

  printf("%u", (unsigned int)arg0);
}

pid$target:libthr:pthread_mutex_destroy:entry  {

  printf("%u", (unsigned int)arg0);
}

Ran this on omp_printf, then a bit of awk

awk '/destroy/{print $4}' t.out | sort -n > destroy awk '/init/{print $4}' t.out | sort -n > init

(could probably do that in dtrace, but I'm better at awk)

then a diff. That just confirmed what I saw in gdb (with less chance of a mistake) One mutex is initialiized but not destroyed 2 are destroyed but no init (these are from C++ using the init macro) 10 have matching iit and destroy

Son nothing seems wrong (other than the 'leaking' init).

Need to debug DRD to try to find out what is going on.

paulfloyd commented 3 years ago

Repeating the above exercise with some debug traces in DRD I see what looks like

init 10 guest memory addresses with matching destroy 1 guest memory address without matching destroy 9 host memory addredded with matching destroy

destroy 8 guest memory addresses with matching init 2 guest memory addresses without matching init 9 host memory addresses all with matching inits

paulfloyd commented 3 years ago

Back on i386

Breakpoint 1, vgDrd_bm_access_range_store (bm=0x4299458, a1=32, a2=31) at ./drd_bitmap.c:239 239 tl_assert(a1 <= a2); (gdb) Continuing.

drd: ./drd_bitmap.c:239 (void vgDrd_bm_access_range_store(struct bitmap *const, const Addr, const Addr)): Assertion 'a1 <= a2' failed.

32 and 31 ???

Stacktrace

1 0x380c926c in bm_access_store_triggers_conflict (a1=32, a2=31) at ./drd_thread_bitmap.h:183

(gdb) bt

0 vgDrd_bm_access_range_store (bm=0x4299458, a1=32, a2=31) at ./drd_bitmap.c:239

1 0x380c926c in bm_access_store_triggers_conflict (a1=32, a2=31) at ./drd_thread_bitmap.h:183

2 vgDrd_trace_store (addr=32, size=4294967295) at drd_load_store.c:251

3 0x38178ac0 in vgSysWrap_freebsd_sys_cpuset_getaffinity_after (tid=, arrghs=, status=) at m_syswrap/syswrap-freebsd.c:4846

4 0x381617f7 in vgPlain_post_syscall (tid=1) at m_syswrap/syswrap-main.c:2457

5 0x38161399 in vgPlain_client_syscall (tid=1, trc=77) at m_syswrap/syswrap-main.c:2378

6 0x3815f536 in handle_syscall (tid=1, trc=77) at m_scheduler/scheduler.c:1211

7 0x3815d8b4 in vgPlain_scheduler (tid=1) at m_scheduler/scheduler.c:1529

8 0x3816ae95 in thread_wrapper (tidW=1) at m_syswrap/syswrap-freebsd.c:107

9 run_a_thread_NORETURN (tidW=) at m_syswrap/syswrap-freebsd.c:161

10 0x00000000 in ?? ()

This is a call to

// SYS_cpuset_getaffinity  487
// int cpuset_getaffinity(cpulevel_t level, cpuwhich_t which, id_t id,
//                        size_t setsize, cpuset_t *mask);
PRE(sys_cpuset_getaffinity)
{
   PRINT("sys_cpuset_getaffinity ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1, ARG2,
         ARG3, ARG4, ARG5);
   PRE_REG_READ5(int, "cpuset_getaffinity",
                 int, level, int, which, long, id,
                 size_t, setsize, void *, mask);
   PRE_MEM_WRITE("cpuset_getaffinity", ARG5, ARG4);
}

POST(sys_cpuset_getaffinity)
{
   vg_assert(SUCCESS);
   if (RES == 0)
      POST_MEM_WRITE( ARG5, ARG4 ); <==== crash here
}

Debugging in Valgrind

(gdb) p syscallInfo[tid]
$10 = {orig_args = {klass = 0, sysno = 487, arg1 = 3, arg2 = 1, arg3 = 4294967295, arg4 = 4294967295, arg5 = 32, arg6 = 111150320, arg7 = 99367424, arg8 = 496}, args = {klass = 0, sysno = 487, arg1 = 3, arg2 = 1, arg3 = 4294967295, arg4 = 4294967295, arg5 = 32, arg6 = 111150320, arg7 = 99367424, arg8 = 496}, status = {what = SsComplete, sres = {_val = 0, _val2 = 111150320, _isError = 0 '\000', padding = "\000\000"}}, flags = 0}

So that's a tid of -1 a size of -1 and an address of 32

And running the testcase with ktrace

2043 omp_printf CALL cpuset_getaffinity(0x3,0x1,0xffffffff,0xffffffff,0x20,0x2072e120) 2043 omp_printf RET cpuset_getaffinity 0

/usr/src/sys/compat/freebsd32/syscalls.master contains

487 AUE_NULL STD { int freebsd32_cpuset_getaffinity( \ cpulevel_t level, cpuwhich_t which, \ uint32_t id1, uint32_t id2, \ size_t cpusetsize, \ cpuset_t mask); } 488 AUE_NULL STD { int freebsd32_cpuset_setaffinity( \ cpulevel_t level, cpuwhich_t which, \ uint32_t id1, uint32_t id2, \ size_t cpusetsize, \ const cpuset_t mask); }

So this needs to be split into x86 and amd64 versions.

paulfloyd commented 3 years ago

Fixed with

To github.com:paulfloyd/freebsd_valgrind.git e0ca298c3..2c7457638 freebsd -> freebsd