Hello, I am struggling to understand a backtrace given to me by Helgrind, because it seems to be impossible:
==16699== Helgrind, a thread error detector ==16699== Copyright (C) 2007-2015, and GNU GPL'd, by OpenWorks LLP et al. ==16699== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info ==16699== Command: ./testfs --noblock /lib mnt ==16699== Parent PID: 3636 [...] ==16699== Lock at 0x6520E10 was first observed ==16699== at 0x4C3010C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==16699== by 0x1146B1: __gthread_mutex_lock (gthr-default.h:748) ==16699== by 0x1146B1: lock (std_mutex.h:103) ==16699== by 0x1146B1: lock_guard (std_mutex.h:162) ==16699== by 0x1146B1: sfs_opendir(fuse_req*, unsigned long, fuse_file_info*) (testfs.cpp:870) ==16699== by 0x4E5325B: do_opendir (fuse_lowlevel.c:1442) ==16699== by 0x4E54170: fuse_session_process_buf_int (fuse_lowlevel.c:2579) ==16699== by 0x4E4FE00: fuse_do_work (fuse_loop_mt.c:163) ==16699== by 0x4C32D06: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==16699== by 0x507F493: start_thread (pthread_create.c:333) ==16699== by 0x5916ACE: clone (clone.S:97) ==16699== Address 0x6520e10 is 16 bytes inside a block of size 56 alloc'd ==16699== at 0x4C2D8CF: operator new(unsigned long, std::nothrow_t const&) (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==16699== by 0x1147F0: sfs_opendir(fuse_req*, unsigned long, fuse_file_info*) (testfs.cpp:861) ==16699== by 0x4E5325B: do_opendir (fuse_lowlevel.c:1442) ==16699== by 0x4E54170: fuse_session_process_buf_int (fuse_lowlevel.c:2579) ==16699== by 0x4E4FE00: fuse_do_work (fuse_loop_mt.c:163) ==16699== by 0x4C32D06: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==16699== by 0x507F493: start_thread (pthread_create.c:333) ==16699== by 0x5916ACE: clone (clone.S:97) ==16699== Block was alloc'd by thread #4 ==16699== ==16699== Lock at 0x654A250 was first observed ==16699== at 0x4C3010C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==16699== by 0x1146B1: __gthread_mutex_lock (gthr-default.h:748) ==16699== by 0x1146B1: lock (std_mutex.h:103) ==16699== by 0x1146B1: lock_guard (std_mutex.h:162) ==16699== by 0x1146B1: sfs_opendir(fuse_req*, unsigned long, fuse_file_info*) (testfs.cpp:870) ==16699== by 0x4E5325B: do_opendir (fuse_lowlevel.c:1442) ==16699== by 0x4E54170: fuse_session_process_buf_int (fuse_lowlevel.c:2579) ==16699== by 0x4E4FE00: fuse_do_work (fuse_loop_mt.c:163) ==16699== by 0x4C32D06: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==16699== by 0x507F493: start_thread (pthread_create.c:333) ==16699== by 0x5916ACE: clone (clone.S:97) ==16699== Address 0x654a250 is 16 bytes inside a block of size 40 alloc'd ==16699== at 0x4C2D63F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==16699== by 0x116979: allocate (new_allocator.h:104) ==16699== by 0x116979: allocate (alloc_traits.h:436) ==16699== by 0x116979: _M_allocate_node<const std::piecewise_construct_t&, std::tuple<const std::pair<long unsigned int, long unsigned int>&>, std::tuple<> > (hashtable_policy.h:1947) ==16699== by 0x116979: operator[] (hashtable_policy.h:595) ==16699== by 0x116979: operator[] (unordered_map.h:904) ==16699== by 0x116979: sfs_do_lookup(fuse_req*, unsigned long, char const*, fuse_entry_param*, bool) [clone .constprop.982] (testfs.cpp:525) ==16699== by 0x116F5D: sfs_do_readdir(fuse_req*, unsigned long, unsigned long, long, fuse_file_info*, int) (testfs.cpp:950) ==16699== by 0x4E51789: do_readdirplus (fuse_lowlevel.c:1470) ==16699== by 0x4E54170: fuse_session_process_buf_int (fuse_lowlevel.c:2579) ==16699== by 0x4E4FE00: fuse_do_work (fuse_loop_mt.c:163) ==16699== by 0x4C32D06: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so) ==16699== by 0x507F493: start_thread (pthread_create.c:333) ==16699== by 0x5916ACE: clone (clone.S:97) ==16699== Block was alloc'd by thread #6 [...] Note that both locks were first seen in testfs.cpp:870. However, (according to Valgrind) the first lock was allocated in testfs.cpp:861 and the second in testfs.cpp:525. However, the relevant code in testfs.cpp looks like this: static void sfs_opendir(fuse_req_t req, fuse_ino_t ino, fuse_file_info *fi) { [...] auto d = new (nothrow) DirHandle; // === line 861 === if (d == nullptr) { fuse_reply_err(req, ENOMEM); return; } // Make Helgrind happy - it can't know that there's an implicit // synchronization due to the fact that other threads cannot // access d until we've called fuse_reply_*. lock_guard<mutex> g {d->m}; // === line 870 === In other words, a lock that is first seen in line 870 cannot have been allocated anywhere other than line 861. It is a fresh, local variable pointing at a newly allocated buffer. Therefore, it seems to me that the backtrace given for the allocation of the second lock cannot possibly be correct. Am I missing something? Best, -Nikolaus -- GPG Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F »Time flies like an arrow, fruit flies like a Banana.« _______________________________________________ Valgrind-users mailing list Valgrind-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/valgrind-users