Project

General

Profile

Actions

Bug #2664

closed

scenario template: ndn::Name double free in __cxa_finalize

Added by Junxiao Shi about 9 years ago. Updated almost 9 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
build
Target version:
-
Start date:
03/22/2015
Due date:
% Done:

100%

Estimated time:
0.50 h

Description

Steps to reproduce:

  1. install ndnSIM, and apply #2662 note-1 workaround
  2. clone ndnSIM-scenario-template
  3. create file ndnSIM-scenario-template/scenarios/hello.cpp with following code:

    #include <ns3/ndnSIM-module.h>
    
    int
    main()
    {
      return 0;
    }
    
  4. execute CXXFLAGS='-std=c++0x -Wall' ./waf configure --debug (#2663 note-1 workaround) followed by ./waf --run=hello

Expected: code builds and scenario terminates without error

Actual: code builds, but scenario fails with *** glibc detected *** build/hello: double free or corruption (!prev): 0x00000000014239d0 ***

======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6( 0x7de16)[0x7fdaaa543e16]
build/hello(__gnu_cxx::new_allocator<ndn::Block>::deallocate(ndn::Block*, unsigned long) 0x20)[0x4d6654]
build/hello(std::_Vector_base<ndn::Block, std::allocator<ndn::Block> >::_M_deallocate(ndn::Block*, unsigned long) 0x32)[0x4d53c4]
build/hello(std::_Vector_base<ndn::Block, std::allocator<ndn::Block> >::~_Vector_base() 0x56)[0x4d4e12]
build/hello(std::vector<ndn::Block, std::allocator<ndn::Block> >::~vector() 0x42)[0x4d3a54]
build/hello(ndn::Block::~Block() 0x1d)[0x4d06df]
build/hello(ndn::Name::~Name() 0x1d)[0x4d0d7b]
/lib/x86_64-linux-gnu/libc.so.6(__cxa_finalize 0x9d)[0x7fdaaa5019cd]
/usr/local/lib/libns3-dev-ndnSIM-debug.so( 0xb0f436)[0x7fdab0d95436]

Files

2664-print-Name-dtor.patch (1.46 KB) 2664-print-Name-dtor.patch Junxiao Shi, 03/23/2015 09:39 AM
patch_ndnsim_scenario.diff (2.18 KB) patch_ndnsim_scenario.diff Christian Kreuzberger, 03/24/2015 12:57 AM

Related issues 1 (0 open1 closed)

Related to ChronoSync - Bug #2842: "double free" reported when smart pointer is created outside of the wrapper classClosed05/28/2015

Actions
Actions #1

Updated by Junxiao Shi about 9 years ago

Workaround:
At end of simulation scenario's main function, add std::abort().

This does not fix the double free problem, but can suppress the error because __cxa_finalize is not executed if program is aborted.

Actions #2

Updated by Christian Kreuzberger about 9 years ago

I am getting the same error when trying ndn-simple via the scenario template.

Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
*** Error in `/home/ckreuz/ndnSIM/my-simulations/build/ndn-simple': double free or corruption (!prev): 0x000000000089ef70 ***

Program received signal SIGABRT, Aborted.
0x00007fffee58acc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007fffee58acc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007fffee58e0d8 in __GI_abort () at abort.c:89
#2  0x00007fffee5c7394 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7fffee6d5b28 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007fffee5d366e in malloc_printerr (ptr=<optimized out>, str=0x7fffee6d5c10 "double free or corruption (!prev)", action=1) at malloc.c:4996
#4  _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3840
#5  0x00007ffff3bd41bf in deallocate (this=<optimized out>, __p=<optimized out>) at /usr/include/c++/4.8/ext/new_allocator.h:110
#6  _M_deallocate (this=<optimized out>, __n=<optimized out>, __p=<optimized out>) at /usr/include/c++/4.8/bits/stl_vector.h:174
#7  ~_Vector_base (this=0x79abd0 <ndn::nfd::CommandOptions::DEFAULT_PREFIX+80>, __in_chrg=<optimized out>) at /usr/include/c++/4.8/bits/stl_vector.h:160
#8  ~vector (this=0x79abd0 <ndn::nfd::CommandOptions::DEFAULT_PREFIX+80>, __in_chrg=<optimized out>) at /usr/include/c++/4.8/bits/stl_vector.h:416
#9  ndn::Block::~Block (this=0x79ab90 <ndn::nfd::CommandOptions::DEFAULT_PREFIX+16>, __in_chrg=<optimized out>) at /usr/local/include/ndn-cxx/encoding/block.hpp:43
#10 0x00007ffff3bd6bad in ndn::Name::~Name (this=0x79ab80 <ndn::nfd::CommandOptions::DEFAULT_PREFIX>, __in_chrg=<optimized out>) at /usr/local/include/ndn-cxx/name.hpp:39
#11 0x00007fffee5905ea in __cxa_finalize (d=0x7ffff4072360) at cxa_finalize.c:56
#12 0x00007ffff3bc5c83 in __do_global_dtors_aux () from /usr/local/lib/libns3-dev-ndnSIM-optimized.so
#13 0x00007fffffffde10 in ?? ()
#14 0x00007ffff7dea73a in _dl_fini () at dl-fini.c:252

Additionally, here is the output from valgrind for build/hello:
http://pastebin.com/y32vBm1j

It looks like there are several invalid free and delete commands, probably related to Name/Block. Though I don't have time to dig into this problem.

Actions #3

Updated by Junxiao Shi about 9 years ago

The Name being double freed is ndn::nfd::CommandOptions::DEFAULT_PREFIX. I found this out with the following method:

  1. apply 2664-print-Name-dtor.patch to ndn-cxx

  2. run scenario in gdb; I added std::cout << "hello" << std::endl; in the scenario to show where cleanup starts.

    (gdb) run
    Starting program: /home/shijunxiao/ndnSIM-scenario-template/build/hello 
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    Name::~Name(0x7fffffffe2a0 /)
    Name::~Name(0x7fffffffdcf0 /)
    Name::~Name(0x7fffffffdee0 /)
    hello
    Name::~Name(0xabbe60 /723821fd-f534-44b3-80d9-44bf5f58bbbb)
    Name::~Name(0xabbb40 /localhost/nfd)
    hello: ../src/name.cpp:87: ndn::Name::~Name(): Assertion `it != getAllNameSet().end()' failed.
    
    Program received signal SIGABRT, Aborted.
    0x00007fffeb4ba0d5 in __GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
    64  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
    (gdb) bt
    #0  0x00007fffeb4ba0d5 in __GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
    #1  0x00007fffeb4bd83b in __GI_abort () at abort.c:91
    #2  0x00007fffeb4b2d9e in __assert_fail_base (fmt=<optimized out>, assertion=0x7d6950 "it != getAllNameSet().end()", 
        file=0x7d6940 "../src/name.cpp", line=<optimized out>, function=<optimized out>) at assert.c:94
    #3  0x00007fffeb4b2e42 in __GI___assert_fail (assertion=0x7d6950 "it != getAllNameSet().end()", file=0x7d6940 "../src/name.cpp", 
        line=87, function=0x7d6b10 "ndn::Name::~Name()") at assert.c:103
    #4  0x00000000006c7862 in ndn::Name::~Name (this=0xabbb40, __in_chrg=<optimized out>) at ../src/name.cpp:87
    #5  0x00007fffeb4bf9cd in __cxa_finalize (d=0x7ffff27df7e0) at cxa_finalize.c:56
    #6  0x00007ffff1f21976 in __do_global_dtors_aux () from /home/shijunxiao/local/lib/libns3-dev-ndnSIM-debug.so
    

    Stack frame 4 shows the Name being destructed is 0xabbb40, which has been destructed earlier and its value was /localhost/nfd.

    The low address also indicates that it's a static constant.

  3. There are only two Name constants of this value in the code: ndn-cxx/src/management/nfd-command-options.cpp and ndnSIM/model/ndn-l3-protocol.cpp.

    Changing the value of ndn::nfd::CommandOptions::DEFAULT_PREFIX to something else, and gdb shows the Name changed, so that I can conclude ndn::nfd::CommandOptions::DEFAULT_PREFIX is the Name being double freed.

This Bug is caused by linking ndn-cxx static library twice: once in libns3-dev-ndnSIM-debug.so and again in the scenario binary.

After those analysis, I have found the solution. Please add me as a Developer of ndnSIM Redmine site, and assign this issue to me. I'll submit the solution afterwards.

Actions #4

Updated by Christian Kreuzberger about 9 years ago

As yous aid, the problem is caused by ndn-cxx STATIC library being linked twice. The fix is not to "fix" ndn::Data (though obviously this could be another problem), but to fix the build scripts.
The changes are simple:
i) (this is preliminary and just fixes some warnings in g++/gcc):

remove -pedantic from .waf-tools/default-compiler-flags.py

ii) add a waf-conf "check" to wscript, that checks that boost is at least at version 1.53 and in addition that boost lib system and iostreams are available

iii) fix waf-build by changing the deps from NDN_CXX + ... to BOOST BOOST_IOSTREAMS + ...

I've done that, and the patch is attached.

Actions #5

Updated by Junxiao Shi about 9 years ago

My solution is much simpler than this. I'm waiting for this Bug to be assigned to me before uploading the solution.

Actions #6

Updated by Junxiao Shi about 9 years ago

  • Tracker changed from Task to Bug
  • Category set to build
  • Status changed from New to In Progress
  • Assignee set to Junxiao Shi
  • Estimated time set to 0.50 h
Actions #7

Updated by Junxiao Shi about 9 years ago

  • Status changed from In Progress to Code review
  • % Done changed from 0 to 100
Actions #8

Updated by Junxiao Shi about 9 years ago

The PullRequest was rejected with the following reason:

This is not right. The library needs to be linked, as in some cases it is needed to use ndn-cxx directly from the extensions or scenarios.

I disagree with this reason.

Not linking ndn-cxx in scenario does not prevent the scenario to use ndn-cxx directly.

  • The compiler can find ndn-cxx headers because pkg-config --cflags libndn-cxx output is appended.
  • The linker can find ndn-cxx symbols because they appear in libns3*-ndnSIM-*.so.

The correct way is to use ndn-cxx as a shared library (though this option is not yet available for cxx...).

Yes, but we don't have to wait for that, given there's a simple solution.

Actions #9

Updated by Junxiao Shi almost 9 years ago

  • Related to Bug #2842: "double free" reported when smart pointer is created outside of the wrapper class added
Actions #10

Updated by Junxiao Shi almost 9 years ago

  • Status changed from Code review to Closed

The bug no longer exists when ndn-cxx is installed as a shared library.

Actions

Also available in: Atom PDF