Re: [DynInst_API:] Type conflict building parseAPI example


Date: Wed, 6 Feb 2013 14:28:01 +0000
From: "E.Robbins" <er209@xxxxxxxxxx>
Subject: Re: [DynInst_API:] Type conflict building parseAPI example
Aha, ok, I thought it might be something like that.

So, the valgrind output is below, the crash was caused by deleting the SymtabCodeSource object (sts). Sorry for the long text!

Best,
Ed

ed@ubuntu:~/Project/SRGDiff/src/parseAPIexample$ valgrind ./recoverCFG ./mergesort.O2 > mergesort.O2.dot
==27106== Memcheck, a memory error detector
==27106== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==27106== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==27106== Command: ./recoverCFG ./mergesort.O2
==27106==
==27106== Mismatched free() / delete / delete []
==27106==    at 0x4C2A739: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27106==    by 0x4EC8B31: Dyninst::ParseAPI::SymtabCodeSource::~SymtabCodeSource() (SymtabCodeSource.C:198)
==27106==    by 0x4EC8CD8: Dyninst::ParseAPI::SymtabCodeSource::~SymtabCodeSource() (SymtabCodeSource.C:203)
==27106==    by 0x401807: main (recoverCFG.cpp:62)
==27106==  Address 0x7320030 is 0 bytes inside a block of size 48 alloc'd
==27106==    at 0x4C2AF8E: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27106==    by 0x4EC9FCD: Dyninst::ParseAPI::SymtabCodeSource::SymtabCodeSource(char*) (SymtabCodeSource.C:234)
==27106==    by 0x401357: main (recoverCFG.cpp:18)
==27106==
==27106== Invalid free() / delete / delete[] / realloc()
==27106==    at 0x4C2A44B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27106==    by 0x6202C8B: Dyninst::SymtabAPI::Object::~Object() (Object-elf.C:3389)
==27106==    by 0x6203018: Dyninst::SymtabAPI::Object::~Object() (Object-elf.C:3394)
==27106==    by 0x626F228: Dyninst::SymtabAPI::Symtab::~Symtab() (Symtab.C:1883)
==27106==    by 0x626F898: Dyninst::SymtabAPI::Symtab::~Symtab() (Symtab.C:1888)
==27106==    by 0x626C2E0: Dyninst::SymtabAPI::Symtab::closeSymtab(Dyninst::SymtabAPI::Symtab*) (Symtab.C:2069)
==27106==    by 0x4EC8B4B: Dyninst::ParseAPI::SymtabCodeSource::~SymtabCodeSource() (SymtabCodeSource.C:200)
==27106==    by 0x4EC8CD8: Dyninst::ParseAPI::SymtabCodeSource::~SymtabCodeSource() (SymtabCodeSource.C:203)
==27106==    by 0x401807: main (recoverCFG.cpp:62)
==27106==  Address 0x7323a70 is 1,728 bytes inside a block of size 1,776 free'd
==27106==    at 0x4C2A44B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27106==    by 0x6202C8B: Dyninst::SymtabAPI::Object::~Object() (Object-elf.C:3389)
==27106==    by 0x6203018: Dyninst::SymtabAPI::Object::~Object() (Object-elf.C:3394)
==27106==    by 0x626F228: Dyninst::SymtabAPI::Symtab::~Symtab() (Symtab.C:1883)
==27106==    by 0x626F898: Dyninst::SymtabAPI::Symtab::~Symtab() (Symtab.C:1888)
==27106==    by 0x626C2E0: Dyninst::SymtabAPI::Symtab::closeSymtab(Dyninst::SymtabAPI::Symtab*) (Symtab.C:2069)
==27106==    by 0x4EC8B4B: Dyninst::ParseAPI::SymtabCodeSource::~SymtabCodeSource() (SymtabCodeSource.C:200)
==27106==    by 0x4EC8CD8: Dyninst::ParseAPI::SymtabCodeSource::~SymtabCodeSource() (SymtabCodeSource.C:203)
==27106==    by 0x401807: main (recoverCFG.cpp:62)
==27106==

==27106== Invalid read of size 8
==27106==    at 0x4EE3617: Dyninst::ParseAPI::Block::~Block() (Block.C:63)
==27106==    by 0x4EE3788: Dyninst::ParseAPI::Block::~Block() (Block.C:66)
==27106==    by 0x4EDD12E: Dyninst::ParseAPI::CFGFactory::destroy_all() (CFGFactory.C:191)
==27106==    by 0x4EDD198: Dyninst::ParseAPI::CFGFactory::~CFGFactory() (CFGFactory.C:82)
==27106==    by 0x4EE4138: Dyninst::ParseAPI::CodeObject::~CodeObject() (CodeObject.C:101)
==27106==    by 0x40181B: main (recoverCFG.cpp:63)
==27106==  Address 0x731fe30 is 0 bytes inside a block of size 184 free'd
==27106==    at 0x4C2A44B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27106==    by 0x401807: main (recoverCFG.cpp:62)
==27106==
==27106== Invalid read of size 8
==27106==    at 0x4EC0928: Dyninst::InsnAdapter::IA_IAPI::~IA_IAPI() (stl_vector.h:403)
==27106==    by 0x4EE3642: Dyninst::ParseAPI::Block::~Block() (Block.C:63)
==27106==    by 0x4EE3788: Dyninst::ParseAPI::Block::~Block() (Block.C:66)
==27106==    by 0x4EDD12E: Dyninst::ParseAPI::CFGFactory::destroy_all() (CFGFactory.C:191)
==27106==    by 0x4EDD198: Dyninst::ParseAPI::CFGFactory::~CFGFactory() (CFGFactory.C:82)
==27106==    by 0x4EE4138: Dyninst::ParseAPI::CodeObject::~CodeObject() (CodeObject.C:101)
==27106==    by 0x40181B: main (recoverCFG.cpp:63)
==27106==  Address 0x731fea0 is 112 bytes inside a block of size 184 free'd
==27106==    at 0x4C2A44B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27106==    by 0x401807: main (recoverCFG.cpp:62)
==27106==
==27106== Invalid read of size 8
==27106==    at 0x4EC092C: Dyninst::InsnAdapter::IA_IAPI::~IA_IAPI() (stl_vector.h:403)
==27106==    by 0x4EE3642: Dyninst::ParseAPI::Block::~Block() (Block.C:63)
==27106==    by 0x4EE3788: Dyninst::ParseAPI::Block::~Block() (Block.C:66)
==27106==    by 0x4EDD12E: Dyninst::ParseAPI::CFGFactory::destroy_all() (CFGFactory.C:191)
==27106==    by 0x4EDD198: Dyninst::ParseAPI::CFGFactory::~CFGFactory() (CFGFactory.C:82)
==27106==    by 0x4EE4138: Dyninst::ParseAPI::CodeObject::~CodeObject() (CodeObject.C:101)
==27106==    by 0x40181B: main (recoverCFG.cpp:63)
==27106==  Address 0x731fe98 is 104 bytes inside a block of size 184 free'd
==27106==    at 0x4C2A44B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27106==    by 0x401807: main (recoverCFG.cpp:62)
==27106==
==27106== Invalid write of size 8
==27106==    at 0x4EC0937: Dyninst::InsnAdapter::IA_IAPI::~IA_IAPI() (IA_IAPI.h:64)
==27106==    by 0x4EE3642: Dyninst::ParseAPI::Block::~Block() (Block.C:63)
==27106==    by 0x4EE3788: Dyninst::ParseAPI::Block::~Block() (Block.C:66)
==27106==    by 0x4EDD12E: Dyninst::ParseAPI::CFGFactory::destroy_all() (CFGFactory.C:191)
==27106==    by 0x4EDD198: Dyninst::ParseAPI::CFGFactory::~CFGFactory() (CFGFactory.C:82)
==27106==    by 0x4EE4138: Dyninst::ParseAPI::CodeObject::~CodeObject() (CodeObject.C:101)
==27106==    by 0x40181B: main (recoverCFG.cpp:63)
==27106==  Address 0x731fe30 is 0 bytes inside a block of size 184 free'd
==27106==    at 0x4C2A44B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27106==    by 0x401807: main (recoverCFG.cpp:62)
==27106==
==27106== Invalid read of size 8
==27106==    at 0x4EC095F: Dyninst::InsnAdapter::IA_IAPI::~IA_IAPI() (shared_count.hpp:305)
==27106==    by 0x4EE3642: Dyninst::ParseAPI::Block::~Block() (Block.C:63)
==27106==    by 0x4EE3788: Dyninst::ParseAPI::Block::~Block() (Block.C:66)
==27106==    by 0x4EDD12E: Dyninst::ParseAPI::CFGFactory::destroy_all() (CFGFactory.C:191)
==27106==    by 0x4EDD198: Dyninst::ParseAPI::CFGFactory::~CFGFactory() (CFGFactory.C:82)
==27106==    by 0x4EE4138: Dyninst::ParseAPI::CodeObject::~CodeObject() (CodeObject.C:101)
==27106==    by 0x40181B: main (recoverCFG.cpp:63)
==27106==  Address 0x25 is not stack'd, malloc'd or (recently) free'd
==27106==
==27106==
==27106== Process terminating with default action of signal 11 (SIGSEGV)
==27106==  Access not within mapped region at address 0x25
==27106==    at 0x4EC095F: Dyninst::InsnAdapter::IA_IAPI::~IA_IAPI() (shared_count.hpp:305)
==27106==    by 0x4EE3642: Dyninst::ParseAPI::Block::~Block() (Block.C:63)
==27106==    by 0x4EE3788: Dyninst::ParseAPI::Block::~Block() (Block.C:66)
==27106==    by 0x4EDD12E: Dyninst::ParseAPI::CFGFactory::destroy_all() (CFGFactory.C:191)
==27106==    by 0x4EDD198: Dyninst::ParseAPI::CFGFactory::~CFGFactory() (CFGFactory.C:82)
==27106==    by 0x4EE4138: Dyninst::ParseAPI::CodeObject::~CodeObject() (CodeObject.C:101)
==27106==    by 0x40181B: main (recoverCFG.cpp:63)
==27106==  If you believe this happened as a result of a stack
==27106==  overflow in your program's main thread (unlikely but
==27106==  possible), you can try to increase the size of the
==27106==  main thread stack using the --main-stacksize= flag.
==27106==  The main thread stack size used in this run was 8388608.
==27106==
==27106== HEAP SUMMARY:
==27106==     in use at exit: 300,883 bytes in 4,734 blocks
==27106==   total heap usage: 13,984 allocs, 9,286 frees, 1,298,981 bytes allocated
==27106==
==27106== LEAK SUMMARY:
==27106==    definitely lost: 96 bytes in 1 blocks
==27106==    indirectly lost: 0 bytes in 0 blocks
==27106==      possibly lost: 38,523 bytes in 1,125 blocks
==27106==    still reachable: 262,264 bytes in 3,608 blocks
==27106==         suppressed: 0 bytes in 0 blocks
==27106== Rerun with --leak-check=full to see details of leaked memory
==27106==
==27106== For counts of detected and suppressed errors, rerun with: -v
==27106== ERROR SUMMARY: 42 errors from 7 contexts (suppressed: 2 from 2)

Segmentation fault (core dumped)

________________________________________
From: Andrew Bernat [bernat@xxxxxxxxxxx]
Sent: 05 February 2013 18:58
To: E.Robbins
Cc: dyninst-api@xxxxxxxxxxx
Subject: Re: [DynInst_API:] Type conflict building parseAPI example

On Feb 5, 2013, at 12:52 PM, E.Robbins <er209@xxxxxxxxxx<mailto:er209@xxxxxxxxxx>> wrote:

I do have valgrind - I'll check it out tomorrow. Did you want me to do some particular check (I mostly use it for leak checking)?

The default run will identify memory errors. I'd like to know what we're double-deleting, since it seems to vary by platform. Odd.

I find it a bit strange that when the control flow recovery runs into a call it creates an edge to the called function *and* one to the following block (the one starting immediately after the call site). Shouldn't it make an edge going to the call and then an edge from the return block of the called function to the following block? Otherwise you are assuming that the function will return. I am sure there is a good reason for this (probably because you can't always find the return of a function?) but I just wondered what the reasoning was?

It's to make intra-function analysis easier. We create a virtual edge with a type of CALL_FT to link the call to where execution will return. We check for non-returning functions and omit CALL_FT if we find them, though that analysis turns out to be remarkably difficult.

Basically, it's to make life easy for people that don't want full interprocedural analysis.

Drew


Cheers,
Ed

________________________________________
From: Andrew Bernat [bernat@xxxxxxxxxxx<mailto:bernat@xxxxxxxxxxx>]
Sent: 05 February 2013 18:01
Subject: Re: [DynInst_API:] Type conflict building parseAPI example

Thanks, this is very nice.

WRT the crash - do you have valgrind on your system? If so, could you run it and send me the output? I'd be interested to know why delete isn't working. Not that I'm at all surprised - memory management is a pain.

Drew

On Feb 5, 2013, at 8:14 AM, E.Robbins <er209@xxxxxxxxxx<mailto:er209@xxxxxxxxxx><mailto:er209@xxxxxxxxxx>> wrote:

Hi again,
I added a couple of lines to your example and now it groups nodes from the same function into clusters and labels function nodes with the name of the function... makes it a bit clearer what is going on. Give it a try! I've attached it.

BTW, I commented out the deletes at the end because one of them causes a crash, at least on my system.

Cheers,
Ed

--
Andrew Bernat
Paradyn Project
bernat@xxxxxxxxxxx<mailto:bernat@xxxxxxxxxxx><mailto:bernat@xxxxxxxxxxx>
http://www.cs.wisc.edu/~bernat





--
Andrew Bernat
Paradyn Project
bernat@xxxxxxxxxxx<mailto:bernat@xxxxxxxxxxx>
http://www.cs.wisc.edu/~bernat



[← Prev in Thread] Current Thread [Next in Thread→]