Boost logo

Boost Users :

From: Robert Mecklenburg (rmecklenburg_at_[hidden])
Date: 2008-05-02 12:11:50


First, please excuse the length of this message, I just want to
provide a clear picture of what's happening.

I'm interested in using the gcc mudflap feature (sort of
valgrind/purify implemented in the compiler) with the boost
libraries.

    http://gcc.gnu.org/wiki/Mudflap_Pointer_Debugging
    http://gcc-hk.internet.bs/summit/2003/mudflap.pdf

Unfortunately, I'm running into serious problems.

Preliminaries:
I'm using gcc 4.2, boost 1.34.1, Ubuntu Linux Hardy Heron.

I found a message from 2006-07-31 discussing mudflap
(http://lists.boost.org/boost-build/2006/07/14546.php), but it only
refers to build flags.

Now for the issue, writing a simple test case (which appears to run
correctly without mudflap instrumentation):

    #define BOOST_TEST_DYN_LINK
    #define BOOST_TEST_MAIN
    #include <boost/test/unit_test.hpp>
    BOOST_AUTO_TEST_CASE(mudflap)
    {
    }

And compiling and running yields:

    $ g++ -g -fmudflapth -c -o mudflapTest.o mudflapTest.cpp
    $ g++ -g -fmudflapth mudflapTest.o /usr/lib/libmudflapth.so.0 \
               -lboost_unit_test_framework -lboost_thread -o mudflapTest
    $ ./mudflapTest
    *******
    mudflap violation 1 (check/write): time=1209744559.152187 ptr=0xbfa3594c size=4
    pc=0xb7e047bd location=`/usr/include/boost/shared_ptr.hpp:149 (boost::shared_ptr<boost::unit_test::ut_detail::callback0_impl<boost::unit_test::ut_detail::unused> >::shared_ptr<boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused, void (*)()> >)'
          /usr/lib/libmudflap.so.0(__mf_check+0x3d) [0xb7e047bd]
          /home/mecklen/s5w/trunk/core/common/src/test/mudflapTest(_ZN5boost10shared_ptrINS_9unit_test9ut_detail14callback0_implINS2_6unusedEEEEC1INS2_16callback0_impl_tIS4_PFvvEEEEEPT_+0x77) [0x804ef79]
          /home/mecklen/s5w/trunk/core/common/src/test/mudflapTest(_ZN5boost9unit_test9callback0INS0_9ut_detail6unusedEEC1IPFvvEEET_+0x33) [0x804efe7]
    number of nearby objects: 0
    *******
    <10 more violations occur here>
    *** No errors detected

Obviously, mudflap believes that there were invalid writes occurring
in the boost libraries. I attempted to debug this by first expanding
the cpp macros and removing the use of unnamed temporaries to yield:

    ...
    boost::unit_test::const_string name("mudflap");
    boost::unit_test::test_case * tc = boost::unit_test::make_test_case(&mudflap_invoker, name);
    static boost::unit_test::ut_detail::auto_test_unit_registrar
    mudflap_registrar(tc, boost::unit_test::ut_detail::auto_tc_exp_fail<mudflap_id>::value);
    ...

Running this under gdb I discover that the alleged violation appears
to occur in the execution of the make_test_case(invoker, name) call,
during the construction of a shared_ptr:

    (gdb) where
    #0 shared_ptr<boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused, void (*)()> > (this=0xbfecbddc, p=0x80d4d28) at /usr/include/boost/shared_ptr.hpp:149
    #1 0x0804ed9d in callback0<void (*)()> (this=0xbfecbddc, f=0x804bf6c <mudflap_invoker>) at /usr/include/boost/test/utils/callback.hpp:111
    #2 0x0804c5cd in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at mudflapTest.cpp:26
    #3 0x0804c65a in global constructors keyed to _ZN5boost9unit_test44_GLOBAL__N_mudflapTest.cpp_00000000_456E4E3F13unit_test_logE () at mudflapTest.cpp:36
    #4 0x0804f4f5 in __do_global_ctors_aux ()
    #5 0x0804bcb4 in _init ()
    #6 0x0804f499 in __libc_csu_init ()
    #7 0xb7b853f1 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6
    #8 0x0804bed1 in _start ()
    *******
    mudflap violation 1 (check/write): time=1209743602.806628 ptr=0xbfecbddc size=4
    ...

The target of the shared pointer appears normal:

    (gdb) p p
    $2 = (boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused,void (*)()> *) 0x80d4d28
    (gdb) p *p
    $3 = (boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused,void (*)()>) {
      <boost::unit_test::ut_detail::callback0_impl<boost::unit_test::ut_detail::unused>> = {
        _vptr.callback0_impl = 0x8051970
      },
      members of boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused,void (*)()>:
      m_f = 0x804bf6c <mudflap_invoker>
    }

The pointers within this object appear to point to valid addresses
with proper data (supporting evidence omitted for brevity).

(I have tried to run the unit test code without shared libraries, but
my attempts at static linking have failed, so far.)

In short, I cannot determine why mudflap thinks this is bogus. I
believe mudflap is implemented correctly, as I've used it successfully
on other non-boost test cases.

Has anyone used mudflap successfully with boost? It seems a powerful
tool if it could be made to work.

Thanks in advance for any suggestions.

--
Robert Mecklenburg

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net