Segfault when calling a method c++ - c++

I am fairly new to c++ and I am a bit stumped by this problem. I am trying to assign a variable from a call to a method in another class but it always segfaults. My code compiles with no warnings and I have checked that all variables are correct in gdb but the function call itself seems to cause a segfault. The code I am using is roughly like the following:
class History{
public:
bool test_history();
};
bool History::test_history(){
std::cout<<"test"; //this line never gets executed
//more code goes in here
return true;
}
class Game{
private:
bool some_function();
public:
History game_actions_history;
};
bool Game::some_function(){
return game_actions_history.test_history();
}
Any tips or advice is greatly appreciated!
EDIT: I edited the code so there is no more local_variable and the value returns directly. But it still segfaults. As for posting the actual code, it's fairly large, what parts should I post?

From what I can see there's nothing wrong with the code you've displayed. However, segfaults often are a good indication that you've got corrupted memory. It's happening some place else besides what you've shown and only happens to impact the code here. I'd look any place you're dealing with arrays, pointers, or any manual memory interactions.

I have used valgrind succesfully with a lot of segfaults.
and have you tried to run gdb with the coredump caused by the segfault? from man gdb:
gdb program core
To create a coredump you might have to set:
ulimit -c unlimited

Shot in the dark. (Game*)this is NULL ?

The code is fine but the example is too incomplete to say what's wrong. Some things I'd suggest:
Add printouts to each class's destructor and constructor:
Game::Game() { cerr << this << " Game::Game" << endl; }
Game::Game(Game const&) { cerr << this << " Game::Game(Game const&)" << endl; }
Game::~Game() { cerr << this << " Game::~Game" << endl; }
bool Game::some_function() { cerr << this << " Game::some_function()" << endl; ... }
This will reveal:
Null object pointers.
Bad/deleted class pointers.
Second, for debugging, I'd strongly recommended sending printouts to cerr instead of cout. cout is usually buffered (for efficiency) before being output, cerr is not (at least, this used to be the case). If your program quits without executing its error handlers, at_exit, etc..., you are more likely to see the output if it is unbuffered and printed immediately.
Thirdly, if your class declarations live in a header, the class definitions, live in one cpp file and the code that uses the class in yet another, you may get this kind of crash if either of the cpp files were not recompiled after you changed the header.
Some other possibilities are:
stack overflow: you've allocated a lot of memory on the stack because of deep recursion or are allocating objects containing large arrays of data as local variables (i.e. not created or the heap with new or malloc))
corrupted class vtable (usually only possible due to dependency errors in your build tools),
corrupted object vtable pointer: possible through misuse of pointers: using pointers to deleted memory, or incorrectly writing to an in-use address. Not likely in your example because there are no virtual functions.
maintaining a pointer or reference to an object allocated on the stack that has been deleted: the printout code above will uncover this case.

I am wondering because you have defined some_function() in private of the Game class. So the code structure which you have mentioned above will also throw error for that.

Related

Calling function within C++ classs not working

I have been working on this simply hobbyist OS, and I have decided to add some C++ support. Here is the simple script I wrote. When I compile it, I get this message:
cp.o: In function `caller':
test.cpp:(.text+0x3a): undefined reference to `__stack_chk_fail'
Here is the script:
class CPP {
public:
int a;
void test(void);
};
void CPP::test(void) {
// Code here
}
int caller() {
CPP caller;
caller.test();
return CPP.a;
}
Try it like this.
class CPP {
public:
int a;
void test(void);
};
void CPP::test(void) {
CPP::a = 4;
}
int caller() {
CPP caller;
caller.test();
return caller.a;
}
int main(){
int called = caller();
std::cout << called << std::endl;
return 0;
}
It seems to me that the linker you are using can't find the library containing a security function crashing the program upon detecting stack smashing. (It may be that the compiler doesn't include the function declaration for some reason? I am not familiar who actually defies this specific function.) Try compiling with -fno-stack-protector or equivalent.
What is the compiler used? A workaround might be defining the function as something like exit(1); or similar. That would produce the intended effect yet fix the problem for now.
I created a test program to show how this actually plays out. Test program:
int main(){
int a[50]; // To have the compiler manage the stack
return 0;
}
With only -O0 as the flag ghidra decompiles this to:
undefined8 main(void){
long in_FS_OFFSET;
if (*(long *)(in_FS_OFFSET + 0x28) != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
With -fno-stack-protector:
undefined8 main(void){
return 0;
}
The array was thrown out by ghidra in decompilation, but we see that the stack protection is missing if you use the flag. There are also some messed up parts of this in ghidra (e.g. int->undefined8), but this is standard in decompilation.
Consequences of using the flag
Compiling without stack protection is not good per se, but it shouldn't affect you in much. If you write some code (that the compiler shouts you about) you can create a buffer overflowable program, which should not be that big of an issue in my optinion.
Alternative
Alternatively have a look at this. They are talking about embedded systems, but the topic seems appropriate.
Why is the code there
Look up stack smashing, but to my knowledge I will try to explain. When the program enters a function (main in this case) it stores the location of the next instruction in the stack.
If you write an OS you probably know what the stack is, but for completeness: The stack is just some memory onto which you can push and off which you can pop data. You always pop the last pushed thing off the stack. C++ and other languages also use the stack as a way to store local variables. The stack is at the end of memory and when you push something, the new thing will be further forward rather than back, it fills up 'backwards'.
You can initialise buffers as a local variable e.g. char[20]. If you filled the buffer without checking the length you might overfill this, and overwrite things in the stack other than the buffer. The return address of the next instruction is in the stack as well. So if we have a program like this:
int test(){
int a;
char buffer[20];
int c;
// someCode;
}
Then the stack will look something like this at someCode:
[ Unused space, c, buffer[0], buffer[1] ..., buffer[19], a, Return Address, variables of calling function ]
Now if I filled the buffer without checking the length I can overwrite a (which is a problem as I can modify how the program runs) or even the return address (which is a major flaw as I might be able to execute malicious shellcode, by injecting it into the buffer). To avoid this compilers insert a 'stack cookie' between a and the return address. If that variable is changed then the program should terminate before calling return, and that is what __stack_chk_fail() is for. It seems that it is defined in some library as well so you might not be able use this, despite technically the compiler being the one that uses this.

how to correctly pass data structures between custom llvm passes

I have a Function pass, called firstPass, which does some analysis and populates:
A a;
where
typedef std::map< std::string, B* > A;
class firstPass : public FunctionPass {
A a;
}
typedef std::vector< C* > D;
class B {
D d;
}
class C {
// some class packing information about basic blocks;
}
Hence I have a map of vectors traversed by std::string.
I wrote associated destructors for these classes. This pass works successfully on its own.
I have another Function pass, called secondPass, needing this structure of type A to make some transformations. I used
bool secondPass::doInitialization(Module &M) {
errs() << "now running secondPass\n";
a = getAnalysis<firstPass>().getA();
return false;
}
void secondPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<firstPass>();
AU.setPreservesAll();
}
The whole code compiles fine, but I get a segmentation fault when printing this structure at the end of my first pass only if I call my second pass (since B* is null).
To be clear:
opt -load ./libCustomLLVMPasses.so -passA < someCode.bc
prints in doFinalization() and exits successfully
opt -load ./libCustomLLVMPasses.so -passA -passB < someCode.bc
gives a segmentation fault.
How should I wrap this data structure and pass it to the second pass without issues? I tried std::unique_ptr instead of raw ones but I couldn't make it work. I'm not sure if this is the correct approach anyway, so any help will be appreciated.
EDIT:
I solved the problem of seg. fault. It was basically me calling getAnalysis in doInitialization(). I wrote a ModulePass to combine my firstPass and secondPass whose runOnModule is shown below.
bool MPass::runOnModule(Module &M) {
for(Function& F : M) {
errs() << "F: " << F.getName() << "\n";
if(!F.getName().equals("main") && !F.isDeclaration())
getAnalysis<firstPass>(F);
}
StringRef main = StringRef("main");
A& a = getAnalysis<firstPass>(*(M.getFunction(main))).getA();
return false;
}
This also gave me to control the order of the functions processed.
Now I can get the output of a pass but cannot use it as an input to another pass. I think this shows that the passes in llvm are self-contained.
I'm not going to comment on the quality of the data structures based on their C++ merit (it's hard to comment on that just by this minimal example).
Moreover, I wouldn't use the doInitialization method, if the actual initialization is that simple, but this is a side comment too. (The doc does not mention anything explicitly about it, but if it is ran once per Module while the runOn method is ran on every Function of that module, it might be an issue).
I suspect that the main issue seems to stem from the fact A a in your firstPass is bound to the lifetime of the pass object, which is over once the pass is done. The simplest change would be to allocate that object on the heap (e.g. new) and return a pointer to it when calling getAnalysis<firstPass>().getA();.
Please note that using this approach might require manual cleanup if you decide to use a raw pointer.

Cause for crash in std::set::insert

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>.

Segmentation fault calling std::map::clear

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.

any possible explanations for this weird crash?

I have a core file I am examining. And I am just stumped at what can be the possible causes for this. Here is the behavoir:
extern sampleclas* someobj;
void func()
{
someobj->MemFuncCall("This is a sample str");
}
My crash is inside MemFuncCall. But when I examine core file, someobj has an address, say abc(this address is properly initialized and not corrupted) , which is different from this pointer in the function stacktrace: sampleclass::MemFuncCall(this=xyz, "This is a sample str")
I was assuming that this pointer will always be the same as address for someobj i.e. abc should always be equal to xyz.
What are the possible cases where these 2 addresses can be different???
Fyi, This app is single threaded.
Ship optimizations can make things appear very strange in a debugger. Recompile in debug mode (optimizations off), and repo.
Another possible explaination is if the calling convention (or definition in general) is wrong for MemFuncCall (there is a disagreement between the header you compiled with and when MemFuncCall was compiled). You have to try hard to get this wrong, though.
It is possible. Maybe some kind of buffer overrun? Maybe the calling convention (or definition in general) is wrong for MemFuncCall (there is a mismatch between the header you compiled with and when MemFuncCall was compiled).
Hard to say.
But since this is single threaded I would try following technique. Usually memory layout in apps is the same between reruns of application. So start your application under debugger, stop it immediately and put two memory breakpoints on addresses 0xabc and 0xxyz. You have good chance of hitting breakpoints once someone is modifying this memory. Maybe than stack traces will help?
In the case of multiple inheritance the this pointer can be different from the pointer to the "real" object:
struct A {
int a;
void fa() { std::cout << "A::this=" << this << std::endl; }
};
struct B {
int b;
void fb() { std::cout << "B::this=" << this << std::endl; }
};
struct C : A, B {
};
int main() {
C obj;
obj.fa();
obj.fb();
}
Here inside obj.fa(), this will point to the A part of obj while inside fb() it will point to the B part. So the this pointers can be different in different methods, and also different from &obj.
As a reason for the crash a possibility would be that someobj was deleted before and the pointer is no longer valid.
since the pointer someobj is defined externally it could the that there is some inconsistencies between your compilation units. try to clean everything and rebuild the project
One thing I can think of is a corruption of vtable.