Boost serialization assertion fail - c++

I use boost's binary serialization and it worked well until now. I have std::list of pointers to serialize for output (oarchive) but serialization fails inside object's serialize() function with MSVC's dialog:
R6010 -abort() has been called
and such string is printed into console window:
Assertion failed: 0 == static_cast<int>(t) || 1 == static_cast<int>(t), file c:\program files\boost\boost_1_44\boost\archive\basic_binary_oprimitive.hpp, line 91
what does it mean?
Project is pretty big, sources are distributed so I cannot post it's code here, but I tried to simulate this error within simple project - there it works fine what is strange.
P.S. I use boost 1.44 with MSVC2010EE on Windows XP. When I click "retry" on "Debug Error!" window debugger shows arrow on the code line next to serialization archive << myList; line - I mean it seems like error occurred at some destructor or something.
When I make changes inside objects serialize() function - they will be applied just when I rebuild whole project (clean before compiling) - but if I just compile it (where IDE shows that all sources which include changed header are recompiled) - no changes will happen at runtime since last version (I tried with printf()) - that's strange.
Could I occasionally set some critical definitions or something?

The line in question says:
// trap usage of invalid uninitialized boolean which would
// otherwise crash on load.
It looks like at some point you are trying to serialize a bool that hasn't been initialized. Without further code we can't help you find which one.

Related

Incompatibility between C++ Google Test, Qt and boost libraries on a VERY simple case (core dumped)

I am starting a C++ project in which I wish to use elements from both the Qt environment and boost libraries. Also, Google Test will be the unit testing framework.
It is the very beginning of the project and therefore it contains a tiny amount of code (a few member accessor functions for one class).
Yet, as soon as I started to compile with boost (boost_filesystem), I got a core dumped in the middle of the tests run by Google Test. These tests were running fine before. The core dump occurs long before I am calling any boost function. Also, even if I comment out the code that call boost functions and just link with boost, I still get the core dump in the same place.
This core dump occurs in the middle of a list of EXPECT_DEATH calls that I use to test that my Q_ASSERT assertions do indeed get triggered on invalid inputs. I know that EXPECT_DEATH is costly but so far it worked fine (before I linked to Boost). In my current test scenario, I must be calling it a little under 100 times. Here is an example:
l_item.setFlags(CorpusStore::FULL_EDGE);
EXPECT_DEATH(l_item.text(), "");
EXPECT_DEATH(l_item.setText("toto"), "");
The code that will trigger the death is:
void CorpusStore::Item::setText(const QString& p_text){
qCDebug(g_cat_store) << QString("setting text to [%1] (len = %2)").arg(p_text).arg(p_text.length());
Q_ASSERT_X((m_flags & (ITEM_IS_VERTEX | ITEM_IS_SIMPLE)) != 0, "Item::setText()", "cannot be a full edge");
Q_ASSERT_X(((m_flags & (ITEM_IS_VERTEX | ITEM_IS_SIMPLE)) == ITEM_IS_SIMPLE) ? (p_text.length() < SIMPLE_EDGE_TEXT_LEN) : true,
"Item::setText()", "simple edge --> length must be < SIMPLE_EDGE_TEXT_LEN");
Q_ASSERT_X(((m_flags & (ITEM_IS_VERTEX | ITEM_IS_SIMPLE)) == (ITEM_IS_VERTEX | ITEM_IS_SIMPLE)) ?
(p_text.length() < SIMPLE_VERTEX_TEXT_LEN) : true,
"Item::setText()", "simple vertex --> length must be < SIMPLE_VERTEX_TEXT_LEN");
Like I said, I have a little under 100 tests that look like this (plus a number of EXPECT_EQ, etc)
I know that people are going to tell me that I should not use so many EXPECT_DEATH to test asserts and that I should use Google Test's own assert macros instead of Qt's. Okay, Okay, but ...
This is what I want to do ...
The core dump should not happen even if I use a million EXPECT_DEATH.
There is obviously a bug somewhere and so it is worth investigating (hint, hint, Boost, Qt and Google Test people)
Here is my main function:
int main(int argc, char *argv[])
{
::testing::InitGoogleTest(&argc, argv);
CorpusStore::CorpusEnv::init();
//CorpusStore::Storage::init();
return RUN_ALL_TESTS();
}
The commented out line in the middle is where the Boost functions would be called. As I said, I get a core dumped nonetheless. CorpusStore::CorpusEnv::init() is my own initialization code that I need to call before the tests begin.
I am using the Qt build system, which may not be familiar to many. In essence it generates a Makefile, just like CMake does. In addition to the Qt libraries, I am just linking with two more: libgtest.a and libboost_filesystem.a
HELP!!....
------------ EDITS ------------
Based on #Some programmer dude comments below.
On the debugger, I am just seeing that the core dump happens in the middle of a malloc call and I can see some disassembled code. But the context (what call caused it) is not clear. Some of the code just before the malloc call contains what appears to be Qt Symbols. The function call stack starts inside the libc-start.c library which, I guess, must be called after a fork call due to the EXPECT_DEATH. What is weird is that this stretch of code worked ok before I started linking with libboost_filesystem.a and no code from that library does appear in the debugger function call stack. If I remove all the boost related code and stop linking to it, my whole test suit works.
This is the situation where it happens (messages from qDebug()):
...
[Debug] 17:14:32.209 (void CorpusStore::Item::setFlags(CorpusStore::FlagField) ../Corpus/corpus_store.cpp:338) "Setting flags to 0x3 (0b0000000000000000000000000000000000000000000000000000000000000011)"
[Debug] 17:14:32.209 (void CorpusStore::Item::setReciprocal(CorpusStore::ItemID) ../Corpus/corpus_store.cpp:498) "setting reciprocal edge to 2416"
[Fatal] 17:14:32.209 ( ../Corpus/corpus_store.cpp:499) ASSERT failure in Item::setReciprocal(): "accessing the reciprocal of an item that is not a full edge", file ../Corpus/corpus_store.cpp, line 499
[Debug] 17:14:32.309 (CorpusStore::ItemID CorpusStore::Item::reciprocal() ../Corpus/corpus_store.cpp:506) "Getting reciprocal edge ..."
[Fatal] 17:14:32.309 ( ../Corpus/corpus_store.cpp:507) ASSERT failure in Item::reciprocal(): "accessing the reciprocal of an item that is not a full edge", file ../Corpus/corpus_store.cpp, line 507
[Debug] 17:14:32.408 (void CorpusStore::Item::setFlags(CorpusStore::FlagField) ../Corpus/corpus_store.cpp:338) "Setting flags to 0x2 (0b0000000000000000000000000000000000000000000000000000000000000010)"
[Debug] 17:14:32.408 (void CorpusStore::Item::setReciprocal(CorpusStore::ItemID) ../Corpus/corpus_store.cpp:498) "setting reciprocal edge to 2417"
[Fatal] 17:14:32.408 ( ../Corpus/corpus_store.cpp:499) ASSERT failure in Item::setReciprocal(): "accessing the reciprocal of an item that is not a full edge", file ../Corpus/corpus_store.cpp, line 499
[Debug] 17:14:32.507 (CorpusStore::ItemID CorpusStore::Item::reciprocal() ../Corpus/corpus_store.cpp:506) "Getting reciprocal edge ..."
[Fatal] 17:14:32.507 ( ../Corpus/corpus_store.cpp:507) ASSERT failure in Item::reciprocal(): "accessing the reciprocal of an item that is not a full edge", file ../Corpus/corpus_store.cpp, line 507
[Debug] 17:14:32.606 (void CorpusStore::Item::setFlags(CorpusStore::FlagField) ../Corpus/corpus_store.cpp:338) "Setting flags to 0x2 (0b0000000000000000000000000000000000000000000000000000000000000010)"
[Debug] 17:14:32.607 (void CorpusStore::Item::setFirstEdge(CorpusStore::ItemID) ../Corpus/corpus_store.cpp:518) "setting first edge to 2327"
[Fatal] 17:14:32.607 ( ../Corpus/corpus_store.cpp:519) ASSERT failure in Item::setFirstEdge(): "accessing the first edge on a non-full item", file ../Corpus/corpus_store.cpp, line 519
Segmentation fault (core dumped)
Each of the [Fatal] messages above corresponds to an EXPECT_DEATH test that has succeeded because a Q_ASSERT has been triggered (see code above). Normally, this output would continue for about 50 more lines, corresponding to more tests. Now it is interrupted in the middle. The point at which it stops doe not seem special in any way. But it stops always at the same point. It is not random.
When the crash happens, I do not see any of my variables (or my function calls) in the debugger, which is why I think it must take place during a fork call before my code gets activated. A problem related to the loading of a library could happen at that point I guess?
This is what I see in the debugger window:
None of it seems particularly helpful.
Found the solution!
Thanks to #sehe and #Genjutsu's comments above.
I recompiled libboost_filesystem.a from sources and it works now.
So the takeaway is: Don't trust Ubuntu/Debian's binary packages. For Boost, at least, they are not guaranteed to work. Why? I have no idea ...

Qt SIGABRT alternative message?

I'm using Qt5.9, a simple check:
assert(pobjNode != NULL);
Will cause the Qt Signal Received error dialog to be displayed which doesn't give any helpful information about where the problem is or what it is.
Is there a way to replace this useless information with something a bit more helpful?
What I'm thinking of is a way to set-up the dialog to display what could be an error in the event of an error.
Q_ASSERT is a custom assert macro which supposedly enhances the standard assert function.
The error message is handled by qFatal(), which can behave slightly better on some platforms than the standard assert macro. For example on Windows it will trigger the Visual Studio debugger at the point where the assertion fails instead of just calling abort().
You can also redirect the output of Qt error message functions such as qFatalto your custom message handler ( with qInstallMessageHandler() ). It can be useful for example if you want to redirect the errors message to a file.
Also note that Q_ASSERT is disabled with the macro QT_NO_DEBUG(while assert is disabled by NDEBUG) : this can be used to separate your asserts between Qt-related code and the rest.
Q_ASSERT_X Prints the message what together with the location where, the source file name and line number if test is false.
Prints the message what together with the location where, the source file name and line number if test is false.
Example:
// File: div.cpp
#include <QtGlobal>
int divide(int a, int b)
{
Q_ASSERT_X(b != 0, "divide", "division by zero");
return a / b;
}
to read more on test and debug.
You might define your own MY_ASSERT macro. On Linux it could even call another function which uses Glibc backtrace functions or Ian Taylor's libbacktrace library (provided your code is compiled with DWARF debug information using g++ -g) and perhaps display such information in a modal dialog, or on stderr. However, it should probably not return. Read also about Qt and Unix signals and signal-safety(7).
But assert detects a bug which you should correct. Try hard to avoid shipping code with such programmer bugs.
On Linux, the usual assert -it is a macro defined in /usr/include/assert.h- will call on failure __assert_fail (in your C library, but you might redefine it yourself) which would indirectly call abort which indirectly makes a core dump which you can inspect post-mortem using the gdb debugger. You only need to enable core dumps (using ulimit -c builtin in your bash terminal).

Running the executable of hdl_simple_viewer.cpp from Point Cloud Library

The Point Cloud library comes with an executable pcl_hdl_viewer_simple that I can run (./pcl_hdl_viewer_simple) without any extra arguments to get live data from a Velodyne LIDAR HDL32.
The source code for this program is supposed to be hdl_viewer_simple.cpp. A simplified version of the code is given on this page which cannot be compiled readily and requires a tiny bit of tweaking to make it compile.
My problem is that the executable that I build myself for both the versions are not able to run. I always get the smart pointer error "Assertion px!=0" error. I am not sure if I am not executing the program in the correct way or what. The executable is supposed to be executed like
./hdl_viewer_simple -calibrationFile hdl32calib.xml -pcapFile file.pcap
in case of playing from previously recorded PCAP files or just ./hdl_viewer_simple if wanting to get live data from the real sensor. However, I always get the assertion failed error.
Has anyone been able to run the executables? I do not want to use the ROS drivers
"Assertion px!=0" is occurring because your pointer is not initialized.
Now that being said, you could initialize it inside your routines, in case the pointer is NULL, especially for data input.
in here, you can try updating the line 83 like this :
CloudConstPtr cloud(new Cloud); //initializing your pointer
and hopefully, it will work.
Cheers,

handling errors from unrar DLL

If you run the command-line version of unrar it logs out vital information when an archive fails to extract.
I'm trying to do the same thing with the unrar DLL.
I've already had to make some changes to the DLL source code to support registering my own callback to handle extraction progress properly.
Now I want to handle error reporting properly.
There is really no documentation on using unrar source.
So I have a working callback function that can be called
CommandData *Cmd
Cmd->ErrorCallback(ERAR_BAD_DATA, Arc.FileName, ArcFileName);
The function works great if I call it next to my progress DLL (so I know the callback works), but I just can't figure out where the errors are being handled.
Specifically I'm after handling the code ERAR_BAD_DATA which I found is handled in extract.cpp ... but that code just doesn't seem to get run.
I also found some calls to RarErrorToDll ... I put the callback there too, nothing.
Any help would be hugely appreciated.
for a bit of context, this is what I was previously doing to catch errors.
bool archiveCorrupt = false;
while((read_header_code = RARReadHeader(archive_data, &header_data)) == 0)
{
process_file_code = RARProcessFile(archive_data, RAR_EXTRACT, m_output_dir, NULL);
if(process_file_code)
{
qDebug() << "Error extracting volume!"
<< header_data.ArcName << " "
<< " with error: " << process_file_code;
archiveCorrupt = true;
break;
}
}
The reason this approach doesn't work is that the error code process_file_code tells you what went wrong, but the archive name in header_data.ArcName is the archive that the file started in, not necessarily where the corruption was. I'm dealing with multi-part archives where one large file will span multiple archives ... so I need to know which archive(s) is corrupt, not just the archive the file started in.
EDIT:
Here is a link to the unrar source code
So I've discovered a place in extract.cpp line 670 that I can place the callback and it does return an error code to my app.
ErrHandler.SetErrorCode(RARX_CRC);
#ifdef RARDLL
Cmd->ErrorCallback(RARX_CRC, Arc.FileName, ArcFileName);
However, this has the same issue as before, where it returns the error at the end of processing the file extracting, rather than at the place where the CRC fails.
If I run the unrar command-line app that you can download from the rarlabs site, it seems to handle it properly and returns the correct error. I can't find text for those errors anywhere in the unrar source, so I can only assume that the unrar source doesn't actually build the unrar app they publish on their site.
Extracting from SL - Cinematic Guitars.part02.rar
... SL - Cinematic Guitars/Cinematic Guitars/Samples/Cinematic Guitars_001.nkx 16%
SL - Cinematic Guitars/Cinematic Guitars/Samples/Cinematic Guitars_001.nkx : packed data CRC failed in volume SL - Cinematic Guitars.part02.rar
I eventually found the answer, after lots of trial and error.
My issue was, I was comparing an old command line version of unrar to the newer source code when looking for the error messages.
The error message has changed in the new source code and is now
packed data checksum error in volume
This is defined in loclang.hpp and called from uiconsole.cpp in the function uiMsgStore:Msg when the error code is UIERROR_CHECKSUMPACKED
This gets called from volume.cpp on line 25
I have added my callback here, and it catches the error perfectly.
I hope this helps someone else if they ever have the misfortune of having to hack unrar source code.

CMake Release made my code stop working properly

I have a C++ program which works well when I compile with no additional options. However, whenever I use cmake -DCMAKE_BUILD_TYPE=Release there is a very specific part of the code which stops working.
Concretely, I have an interface for a Boost Fibonacci Heap. I am calling this function:
narrow_band_.push(myObject);
And this function does the following:
inline void myHeap::push (myStruct & c) {
handles_[c.getIndex()] = heap_.push(c);
}
where heap_ is:
boost::heap::fibonacci_heap<myStruct, boost::heap::compare<compare_func>> heap_;
For some reason the heap_size is not being modified, therefore the rest of the code does not work because the next step is to extract the minimum from the heap and it is always empty.
In Debug mode it works ok. Thank you for your help.
EDIT - Additional info
I have also found this problem: I have a set of code which do simple math operations. In Release mode the results are incorrect. If I just do cout of a couple of variables to check their values, the result changes, which is still incorrect but quite strange.
I solved the problem. It was funny but in this case it was not initialization/timing issues common in the Release mode. It was that the return statement was missing in a couple of functions. In debug mode the output was perfect but in the release mode that failed. I had warnings deactivated, that is why I did not see it before.