I have a c++ program that compiles fine under gcc (4.8.1), icpc (13.1.3), clang++ (3.3) and runs okay except for the clang++ version which crashes with segfault. When I try to run this in the gdb or lldb debugger, I get EXC_BAD_ACCESS with address 0x0. The crash occurs in a member function of a helper class and the debugger claims that this has value 0x0. However going up one level, the pointer pimpl of the helper class is reported to have a non-null value and I can access its data, which look perfectly sensible.
here is some pseudo code (... is not the ellipse, but means "some parameters")
struct helper;
struct foo {
helper* pimpl;
foo(...);
void bar(...);
};
struct helper {
helper(...);
void hbar(...)
{
// crash here with *this = 0x0 according to debugger
}
};
foo::foo(...) : pimpl(new helper(...)) {}
void foo::bar(...)
{
pimpl->hbar(...); // pimpl NOT 0x0 according to debugger ??!
}
What could have gone wrong and how can I find out? Note: the question is NOT: "what is wrong with my code?"
edit 1 Perhaps it is worth mentioning that some of the arguments passed to helper::hbar() have been "optimised away by the compiler", according to the debugger, at the point of foo::bar()), while they have address 0x0 within helper::hbar()
edit 2 If I print out the value of this from within helper::hbar() the error does not occur.
edit 3 The error occurs with -O0 as well as -O2.
edit 4 The first arg of helper::hbar() was taken via const reference. If I change that to by value, everything works fine .... That argument was a spatial vector, similar to std::array<double,3>.
One way to do it - create a log file, print value of pimpl/some variable belonging to pimpl before
pimpl->hbar(...);,
and inside
pimpl->hbar(...);
Compare output from different compilers, try narrow down the problem that way adding more output to log file as you start seeing divergence...
Related
I am traying to code an AVL Tree class in c++ that supports the normal operations for homework.
while trying code the insert member function I found out that when I debug and put a break point in this member function the debugger goes crazy.
to make sure it is not something that I code wrong I changed the code to this simple one to see what happens:
template<class X,class Y>
void AvlTree<X,Y>::insert(const X& key,const Y& data)
{
if(this==nullptr)
{
std::cout<<"I am null"<<std::endl;
}
std::cout<<"insorted"<<std::endl;
}
It turns out that while running the program:
int main()
{
AvlTree<int,int> tree;
tree.insert(1,1);
}
the insert function prints "insorted" but while debugging the program and putting a break point on the <<"insorted"<< it prints "I am null" a lot of times. I don't really get why the this pointer is null while calling it on a non null tree.
is someone knows what seems to be the problem?
I mean a scenario like this: There is some class (I call it victim) with a private data member and another class (named attacker) with some method, which, of course, normally does not have access to private members of other classes and does not even hold a reference to an instance of victim:
extern "C" {
#include <pigpiod_if2.h>
}
class victim {
private:
static bool is_ready;
static bool is_on;
public:
static void init ()
{
is_ready = true;
is_on = true;
}
/* Some other public methods go here. */
}
class attacker {
private:
static int last_read_pin;
public:
static void run ()
{
while (true) {
/* Some sensible code goes here. */
last_read_pin = -1;
time_sleep (0.01); // Using nanosleep () does not change behavior.
}
}
}
This is just a code snippet to illustrate the following question: Is it possible, not just in theory, but also practically, that attacker::run () can modify the values of the two private static vars of victim unintentionally, without addressing any public member of victim, maybe due to undefined behavior or even a compiler bug? Thank you.
UPDATE: After a hint from another user, I did rebuild the complete app using make clean and make. Also, I added the endless loop into my example. The change in is_ready occurs during the sixth run of the loop. Changing the sleep interval does not change behavior, though.
UPDATE #2: I ran my code through gdb with a watch on the is_ready variable, and I got an alert when last_read_pin was set to –1:
Hardware watchpoint 1: is_ready
Old value = true
New value = false
attacker::Run ()
last_read_pin = -1;
UPDATE #3: Moving last_read_pin into the Run () method itself, thereby making it an internal variable, does not help either.
UPDATE #4: After simply commenting out the line of code, which makes so much trouble, the issue still persisten, apparently being caused by one line above, which reads like this:
keypad::last_levels [h] [k] = 0;
I had to comment out this line, too, to get rid of the problem with is_ready being changed.
Could the use of pigpiod cause this issue? I an earlier version, I was using pigpio directly and did not encounter this problem.
Compiled with gcc 4.9.2.
After floating around the code line in question, I found out that the blunder was lying in the line before, which reads as follows:
last_levels [h] [l] = 0;
Unfortunately, h can be < 0. In this case, some kinda exception (array index out of bounds) should be thrown, but unfortunately, it isn't (Does anybody know why?). The gdb gave me the wrong information of the overwrite of is_ready to happen in the following line (Is this maybe a bug?), and I believed this without any criticism. As if this wasn't enough, this error made no problems until I changed my code in a completely different place!
This blunder has cost me quite much time, but now, at last, I know what its cause was, and I corrected it successfully. Thank you anyway for your hints and comments!
I have 220 "unreachable code" warnings in Boost.Variant, class boost::detail::variant::invoke_visitor:
template <typename T>
result_type internal_visit(T& operand, int)
{
return visitor_(operand);
}
.
boost_1_50_0\boost\variant\variant.hpp(859): warning C4702: unreachable code
line return visitor_(operand);.
First of all, how is this possible at all to have unreachable code in this simple single-line function? Which code is unreachable?
I cannot reproduce this warning in a simple case, seems because I don't understand what exactly causes it. The warning appeared after I implemented operator== for classes used in boost::variant.
Environment: VC++ 2010, Boost 1.50
EDIT:
the warning happens only in Release build (optimized), and only if I compare boost::variants. I use boost::variant with primitive and custom types. Custom types implements typical bool operator(CT const& lh, CT const& rh) as free functions.
I had this problem myself in VS 2017. If the compiler determines visitor_(T&) will always throw an exception, the "unreachable" part is the return. If you were to unwrap that into the following:
auto v = visitor_(operand);
return v;
The compiler would call out return v; as unreachable. In my case, I was using a Policy-based class and a NullPolicy threw exceptions. I ended up just removing the exception.
Fun fact: if you have LTCG on, you only get the error during the linking stage, so you don't even know where to start. Turning off LTCG but leaving on optimizations will at least let you narrow it down by making compilation of offending files fail.
Just in case someone else stumbles over the same thing: (I experienced this with MSVS 2017 v15.7.4)
class Widget
{
public:
void bar()
{
foo = 0; // C4702 here
}
void foobar()
{
return; // NOTE direct return here
bar();
}
private:
int foo;
};
This was in old code where someone had "commented out" the entire function foobar() leaving the original code for "future reference". (yes, source control is very hard to use)
Now in release mode the compiler inlined the function bar() which resulted in a C4702: unreachable code warning, but it indicated the first line of function bar() where seemingly nothing was wrong. (actually each line of code after the return; triggered the warning)
I am trying to debug a problem where our program crashes (segfault) in the ´addToOurSet` method below:
class SomeClass {
// ( ... )
void addToOurSet(SomeOtherClass* obj) { ourSet.insert(obj); }
std::set<SomeOtherClass*> ourSet;
};
The crash is hard to reproduce due to (among other things, the complexity and large data size involved, and failure to reproduce in a debug build; the above example is obviously highly simplified). The traceback shows the crash occurring in:
std::_Rb_tree<...>::insert_unique(SomeOtherClass* const&)
My question is: What could cause the ourSet.insert(...) method to crash? As far as I understand, there is nothing with the inserted object itself that could cause it, since it is a pointer. Correct? So am I looking at a problem with the set itself? Obviously, if the set pointer is invalid for some reason, the call could crash, but could for example some operation on the set cause it to be invalid in this way (like for example deleting past its end or something that is forbidden)?
There are several possibilities:
The set itself is invalid (the enclosing SomeClass instance has been deleted, or is being accessed through a dangling pointer etc).
There's a memory corruption somewhere.
I'd probably start with valgrind or a similar tool.
I ran across a similar problem recently. It turned out that I had 2 slightly different declarations for the same class. In foo.h:
class SomeClass {
// ( ... )
void addToOurSet(SomeOtherClass* obj) { ourSet.insert(obj); }
std::set<SomeOtherClass*> ourSet;
};
and in bar.h:
class SomeClass {
// ( ... )
std::vector<SomeOtherClass*> ourSet;
};
It compiled fine but segfaulted deep in <set>.
I have been struggling with a segmentation fault for months, now I'm here to ask for help.
The segmentation fault appears when I call the following function
void foo(..., std::map<MyClass*, double> & x) {
if ( !x.empty() ) x.clear();
...
}
Class A {
private:
map<MyClass*, double> _N;
public:
void f(...) {
foo(..., _N);
...
}
};
//in main routine, the function is called in a loop
A a;
while(...) {
a.f(...);
}
Using gdb, I tacked the error to the line calling the clear() function, it shows "double free or corruption" error, and the program aborts at calling c++/4.1.2/ext/new_allocator.h:94 delete(__P) which further calls free() from the gnu library /lib64/libc.so.6. But since the elements in the map are not allocated by new, why it still calls free() to clear it up. I would really appreciate your comments. Thank you.
Given that the map is owned by another object it suspiciously sounds that the map-owning object was already deleted when the clear was called.
Also note that names starting with underscore and a capital letter are reserved for the implementation - you aren't allowed to use them.
The code looks fine to me. At least with the limited context you have provided. Usually when I run into issues like this I will simply run the valgrind memcheck tool to find the place were the first "delete" happened. Once you know that, these issues can be pretty simple to solve.