CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Dec 2010
    Posts
    4

    Boost invalid block while overloading global new/delete

    Hi,

    I have a problem which appears to a be an invalid memory block that happens during a Boost call to Boost:runtime:cla:arser::~parser. When that global delete is called on that object, C++ asserts on the memory block as an invalid:

    dbgdel.cpp(52):

    /* verify block type */
    _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));

    An investigation I did revealed that the problem happened because of a global overloading of the new/delete operators. Those overloadings are placed in a separate DLL. I discovered that the problem happens only when that DLL is compiled in RELEASE while the main application is compiled in DEBUG.

    So I thought that the Release/Debug build flavors might have created a problem like this in Boost/CRT when overloading new/delete operators. So I then tried to explicitly call to _malloc_dbg and _free_dbg withing the overloading functions even in release mode, but it didn't solve the invalid heap block problem.

    Any idea what the root cause of the problem is? is that situation solvable?

    I should stress that the problem began only when I started to use Boost. Before that CRT never complained about any invalid memory block. So could it be an internal Boost bug?

    Thanks!

  2. #2
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Boost invalid block while overloading global new/delete

    >> I discovered that the problem happens only when that DLL is compiled in RELEASE while the main application is compiled in DEBUG.
    Sounds like memory is being allocated in one module, and freed in the other. This is a problem if one module is using the debug CRT and the other module is using the release CRT. In other words, each module is using it's own unique CRT instance.

    Run all modules in debug mode (using the same CRT), or make your DLL interfaces "self contained" so that the same module that allocated the memory also deallocates it.

    gg

  3. #3
    Join Date
    Dec 2010
    Posts
    4

    Re: Boost invalid block while overloading global new/delete

    The memory is allocated and freed in the same Release DLL. The new/delete operators overloading is delegating the actual implementation into export functions within the DLL that internally call malloc/free as needed. So that's why I'm puzzeld with the issue.

    also, before using Boost, CRT never complained about any memory problem. It's just after using Boost in the EXE application (which is in debug mode), the problem started to show up when the application tears itself down. And it only complains about that Boost's parser class as corrupted.

    I wonder if Boost does something internally that causes this issue

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Boost invalid block while overloading global new/delete

    Quote Originally Posted by 25205899 View Post
    I wonder if Boost does something internally that causes this issue
    Maybe your program always had a bug, and by changing the code, the bug is now exposed. Never blame other libraries before having bonafide proof that it isn't your code. You are dynamically allocating and freeing memory -- that in itself should be a red flag, since handling this yourself is always a risk, and a source for bugs that are very hard to detect and resolve. If it were truly a boost issue, then many programmers would have reported the error/leak/memory corruption within the boost code in the boost forums and website.

    Also, the CRT will never complain if you happen to use "good" memory, regardless of how wrong the code may be. So using the results of the CRT to justify claims that your program is OK is really not proof that your program is correct.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; December 29th, 2010 at 09:56 AM.

  5. #5
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Boost invalid block while overloading global new/delete

    What boost libraries are you using? If UTF, are you using auto-linking?
    http://www.boost.org/doc/libs/1_45_0...ion.procedured
    Using a release boost Dll with a debug Exe would be bad.

    You can also check that multiple CRT's are not being used by running the application and examining the loaded modules using process explorer: http://technet.microsoft.com/en-us/s...rnals/bb896653

    gg

  6. #6
    Join Date
    Dec 2010
    Posts
    4

    Re: Boost invalid block while overloading global new/delete

    I'm using a debug boost over a debug EXE. Like I explained above, I overload new/delete globally and delegate the actual implementation into the other DLL's exported functions that do the malloc/free respectively. That DLL is built in Release mode. So practically, all allocations/deletions are done in the same DLL and memory context.

    I saw this problem when using Boost's unit test framework. Here is the steps to repro the issue:

    1. Create an EXE with standard Boost library to implement aunit test using Boost's API. You can add the BOOST_AUTO_TEST_CASE to create the empty test case
    2. Create a simple DLL and create two exported functions that act as new/delete and simply do malloc/free inside
    3. Within the EXE overload the new/delete globally and call the exported functions from the DLL to delegate the call
    4. Run the application, and during CRT teardown you should get the CRT ASSERT above for the boost::runtime::cla:arser::~parser which is probably one of the internal classes Boost is using for the unit test framework

    You can use the following form of overloading:

    inline void* operator new(size_t size) { return exported_new(size); }
    inline void operator delete(void* pUserData) { return exported_delete(pUserData); }
    Last edited by 25205899; December 29th, 2010 at 11:59 PM.

  7. #7
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Boost invalid block while overloading global new/delete

    >> That DLL is built in Release mode. So practically, all allocations/deletions are done in the same DLL and memory context.
    ...
    >> dbgdel.cpp(52): _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
    Look at the pointer value being passed to delete. Did it come from your new?

    Even though your EXE is auto-linking to the debug UTF DLL - code somewhere in UTF headers may still be generated/compiled during the EXE compilation, and picking up your global new overload. Then the pointer returned from your new is deleted via code inside the UTF DLL, which uses delete from the debug CRT.

    If that doesn't seem to be the case, would you zip and post your solution / project files for for the simple repro [1-4] of the issue. And the version of boost you're using.

    gg

  8. #8
    Join Date
    Dec 2010
    Posts
    4

    Re: Boost invalid block while overloading global new/delete

    The assertion happens during the CRT teardown where all objects are deleted. In my case the assertion happens during the boost::runtime::cla:arser::~parser deletion which is probably part of the Boost's UTF.

    The thing is why there would be inconsistencies between new/delete with regard to Boost memory handling. I would expect that if the new took place in my overloading then why does't the delete would just as well? In other words, what is the scenario in which an object would call my "new" but would be deleted elsewhere despite the fact that the delete is overloaded just as the "new" was.

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Boost invalid block while overloading global new/delete

    Quote Originally Posted by 25205899 View Post
    Here is the steps to repro the issue:

    1. Create an EXE with standard Boost library to implement aunit test using Boost's API. You can add the BOOST_AUTO_TEST_CASE to create the empty test case
    2. Create a simple DLL and create two exported functions that act as new/delete and simply do malloc/free inside
    3. Within the EXE overload the new/delete globally and call the exported functions from the DLL to delegate the call
    4. Run the application, and during CRT teardown you should get the CRT ASSERT above for the boost::runtime::cla:arser::~parser which is probably one of the internal classes Boost is using for the unit test framework

    You can use the following form of overloading:

    inline void* operator new(size_t size) { return exported_new(size); }
    inline void operator delete(void* pUserData) { return exported_delete(pUserData); }
    Remember that we are volunteers here. Why not have the project ready so that all we have to do is compile it and run it?

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Boost invalid block while overloading global new/delete

    Quote Originally Posted by 25205899 View Post
    what is the scenario in which an object would call my "new" but would be deleted elsewhere despite the fact that the delete is overloaded just as the "new" was.
    We don't know if these are facts until we see the code/project. Many times we get posters swearing that they did this or that, and when we see the code, it isn't the case.

    Why not build release versions of everything and retest? If you no longer get the error, then that should be a clue. Mixing up runtime libraries between release/debug/boost, especially when it comes to global/overloaded new and delete, would be a cause for concern.

    Regards,

    Paul McKenzie

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured