Debug Assertion Failed mystery - _pFirstBlock == pHead

May 1, 2013 at 9:50 PM
I have been getting an Debug Assertion Failed! error

Expression: _pFirstBlock == pHead

json::value data;
data[U("entry1")] = json::value::string(U("data")); <==assertion

Release build produce no assertion error. Strangely that code is similar to the unit test in the SDK (I haven't tried the debug build).

Can you tell me what's wrong with this? So I am not sure if it's really a problem or something I can ignore (or suppress preferably).
May 2, 2013 at 6:19 AM

I cannot repro it on my machine, but the assertion suggests that the error happens when a memory object is being deleted, so it's not something you want to ignore. Perhaps this is a case of double-deletion (which should not happen since we only use smart pointers in JSON parser).

Can you reply with a call stack and/or full repro case?

You're not doing anything wrong, as you said yourself this is similar to the unit tests we have (negative_get_field_object etc.)

May 2, 2013 at 3:10 PM
Edited May 2, 2013 at 3:39 PM
Speaking of the witch I found one inconsistency in the build between the SDK and my project.

Casablanca SDK is built with Multi-threaded Debug DLL (/MDd) and my project is using /MTd. I did rebuild the SDK with /MTd but it didn't solve the issue.
casablanca110.dll!_free_dbg_nolock(void * pUserData, int nBlockUse) Line 1424   C++
casablanca110.dll!_free_dbg(void * pUserData, int nBlockUse) Line 1265  C++
casablanca110.dll!operator delete(void * pUserData) Line 54 C++
casablanca110.dll!std::allocator<std::_Container_proxy>::deallocate(std::_Container_proxy * _Ptr, unsigned __int64 __formal) Line 587   C++
casablanca110.dll!std::_String_alloc<0,std::_String_base_types<wchar_t,std::allocator<wchar_t> > >::_Free_proxy() Line 683  C++
casablanca110.dll!std::_String_alloc<0,std::_String_base_types<wchar_t,std::allocator<wchar_t> > >::~_String_alloc<0,std::_String_base_types<wchar_t,std::allocator<wchar_t> > >() Line 656 C++
casablanca110.dll!std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >::~basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >() Line 965   C++
casablanca110.dll!web::json::value::string(std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > value) Line 486    C++
test.exe!wmain(int argc, wchar_t * * argv) Line 48  C++ //this is data[U("entry1")]  = json::value::string(U("data"))
test.exe!__tmainCRTStartup() Line 241   C
test.exe!wmainCRTStartup() Line 164 C
kernel32.dll!BaseThreadInitThunk() Unknown
ntdll.dll!RtlUserThreadStart() Unknown

-- update
I use VS2012 (11.0.60315.01 Update 2). Platform Toolset is "Visual Studio 2012 (v110)
May 2, 2013 at 4:06 PM

That stack trace is all too familiar to me -- the layout of standard strings vary between runtime binaries for different configurations. If I were a betting man, I'd bet that you have a mix of release and debug binaries in your execution folder.

First, though, build your project using /MDd -- Casablanca has not been tested as a static library, so we don't know that it works that way.

Second, if that doesn't help, make sure that you know that all your binaries are either debug or release binaries in the directory where you application is run from. Each time I've seen this, it's been because I've somehow managed to use a Release DLL with a Debug DLL or EXE.

May 2, 2013 at 4:37 PM
Once I switched my project to /MDd it didn't throw assertion error anymore but if I switched both to /MTd it was still failing. You can repro this issue with default console app and the two statements in the original post.

Will this cause the application to be dependent on re-distribuable binaries? That would really increase download size. Would it make more sense to use /MTd and /MT so that there is no binary dependency at run-time?
May 2, 2013 at 7:18 PM
Yes, this is a limitation in the current implementation.

Making static linking work is on our list, but not as high up as many other things. Mostly, this is due to a testing resource constraint -- supporting static linking doubles the number of configurations we have to validate.

The X64 release Casablanca DLL is < 600KB, not tiny, but not extremely large, either. Given how interconnected all the pieces in the library are, static linking is likely to add a significant portion of that to your application size.