Find causing a segmentation fault - c++

I have a shared library for library interposition with an unordered_map.
The unordered_map is filled and consulted through the execution of an application (when intercepting specifics calls).
If I try to find an element in the constructor of the library, it generates a segmentation fault.
Here is the code for the constructor causing the segmentation fault:
void __attribute__((constructor)) init(void) {
void * address = __builtin_extract_return_addr(__builtin_return_address(0));
printf ("Size: %i\n", stats._regions.size()); // works fine
auto regionIt = stats._regions.find(address);
printf ("Never reached\n");
}
Stats is declared in the header, like this:
class Stats {
public
std::unordered_map<void *, RegionInfo> _regions;
}
As said, if I do the find when intercepting specific calls (not in the constructor), it works fine.

Here is the code for the constructor causing the segmentation fault:
You didn't show how the stats global itself is declared, and without that your code is useless (see also MCVE).
But this is almost certainly an instance of static initialization order fiasco.
How can I test if is SIOF? And fix it if that's the case
The usual way to fix SIOF: instead of declaring stats as a global, make it a function-static and return a reference to it, which guarantees that it will be initialized before you access it:
Stats& get_stats()
{
static Stats stats;
return stats;
}
Your constructor will then look like this:
void __attribute__((constructor)) init(void) {
Stats& stats = get_stats();
// rest as before
}
If this fixes the crash, you'll know that it was an instance of SIOF.

Related

Constructor is not called with /NODEFAULTLIB

I'm using /NODEFAULTLIB to disable CRT(C Runtime), however my constructor is not called, which ends up causing an error in std::map (Access violation) because it is not initialized properly, since std::map constructor it's not called.
Code compiled with LLVM 8.0.0, compiled in mode debug x86
class c_test
{
public:
c_test( int a ) // Constructor not called
{
printf( "Test: %i\n", a ); // Doesn't appear and breakpoint is not reached
}
void add( const std::string& key, const std::string& val )
{
_data[ key ] = val;
}
private:
std::map< std::string, std::string > _data;
};
c_test test{ 1337 };
int main()
{
test.add( "qwrqrqr", "23142421" );
test.add( "awrqw", "12asa1faf" );
return 1;
}
I've implemented my own functions new(HeapAlloc), delete(HeapFree), printf, memcpy, memmove, etc, and all are working perfectly, I have no idea why this happening.
Disabling the CRT is madness.
This performs crucial functions, such as static initialisation. Lack of static initialisation is why your map is in a crippled state. I would also wholly expect various parts of the standard library to just stop working; you're really creating a massive problem for yourself.
Don't reinvent little pieces of critical machinery — turn the CRT back on and use the code the experts wrote. There is really nothing of relative value to gain by turning it off.
I discovered the problem and solved, one guy from another forum said that I needed manually call constructors that are stored in pointers in .CRT section, I just did it and it worked perfectly
I just called _GLOBAL__sub_I_main_cpp function that calls my constructor and solved all my problems, thanks for the answers.

Can the code of some C++ class accidentally overwrite a private static variable of another class?

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!

C++ code throwing Seg. Fault

I have a C++ code as follow:
tryIt.h file
class tryIt : public someOtherClass
{
public:
bool insertI ();
private:
CommandI* m_pInsertI;
bool createInsertI();
}
tryIt.cpp file
tryIt ::tryIt () : m_pInsertI(NULL)
{
createInsertI();
}
tryIt ::~tryIt ()
{
if(m_pInsertI!=NULL)
{
delete m_pInsertI;
m_pInsertI=NULL
}
}
bool createInsertI()
{
m_pInsertI = returnFromSomeOtherFunction();
return true;
}
bool insertI()
{
// Over here if I use m_pInsertI anyhow my code fails with seg fault
// even checking if(m_pInsertI==NULL) make the code throw seg fault
}
So the issue is touching m_pInsertI anywhere make my code throw Seg. fault (Signal 11). Even debugged the code with GDB but didn't got any useful info.
Compiler is GCC
Please help.
Sounds like the instance of this class does not exist or damaged.
That is why you can't access any of its members and even if(m_pInsertI==NULL) check raises the exception.
in tryIt.cpp shouldn't
bool createInsertI()
be
bool tryIt::createInsertI()
same with insertI()
I see the following two possibilities:
returnFromSomeOtherFunction() already returns a corrupted pointer
You are copying your instance using the compiler generated methods (see example below)
Example (Rule of three violation)
tryIt instance1; // allocates instance2.m_pInsertI
{
tryIt instance2;
instance1 = instance 2; // performs a shallow copy
} // here, instance2.m_pInsertI is deleted
instance1.insertI(); // access violation
Recommendation:
Whether or not this is cause your problem: Do not implement manual memory management. Simply use a std::unique_ptr<CommandI> for m_pInsertI instead, so you do not need to implement the destructor or copy constructors/operators.

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.

Problems with Static Initialization

I'm having some weird issues with static initalization. I'm using a code generator to generate structs and serialization code for a message passing system I wrote. In order to have a way of easily allocating a message based on it's message id I have my code generator ouput something similar to the following for each message type:
MessageAllocator s_InputPushUserControllerMessageAlloc(INPUT_PUSH_USER_CONTROLLER_MESSAGE_ID, (AllocateMessageFunc)Create_InputPushUserControllerMessage);
The MessageAllocator class basically looks like this:
MessageAllocator::MessageAllocator( uint32_t messageTypeID, AllocateMessageFunc func )
{
if (!s_map) s_map = new std::map<uint32_t, AllocateMessageFunc>();
if (s_map->insert(std::make_pair(messageTypeID, func)).second == false)
{
//duplicate key!
ASSERT(false, L"Nooooo!");
}
s_count++;
}
MessageAllocator::~MessageAllocator()
{
s_count--;
if (s_count == 0) delete s_map;
}
where s_map and s_count are static members of MessageAllocator. This works most of the time but sometimes messages are not added to the map. For example, this particular message is not added unless i call Create_InputPushUserControllerMessage() somewhere in my startup code, however other messages work fine. I thought this might be something to do with the linker incorrectly thinking the type is unreferenced and removing it so I disabled that using the /OPT:NOREF switch (I'm using Visual Studio 2008 SP1) but that had no effect.
I'm aware of the problem of the "static initialization order fiasco" but as far as I know the order in which these objects are created shouldn't alter the result so this seems ok to me.
Any insight here would be appreciated.
Put the static into a class so it is a static member of a class
struct InputPushUserControllerMessageAlloc { static MessageAllocator s_obj; };
MessageAllocator InputPushUserControllerMessageAlloc::s_obj(
INPUT_PUSH_USER_CONTROLLER_MESSAGE_ID,
(AllocateMessageFunc)Create_InputPushUserControllerMessage);
The Standard allows it to delay initialization of objects having namespace scope until any function/object from its translation unit is used. If the initialization has side-effect, it can't be optimized out. But that doesn't forbid delaying it.
Not so of objects having class-scope. So that might forbid it optimizing something there.
I would change s_map from a static class member into a static method member:
std::map<uint32_t,AllocateMessageFunc>& MessageAllocator::getMap()
{
// Initialized on first use and destroyed correctly on program termination.
static std::map<uint32_t,AllocateMessageFunc> s_map;
return s_map;
}
MessageAllocator::MessageAllocator( uint32_t messageTypeID, AllocateMessageFunc func )
{
if (getMap().insert(std::make_pair(messageTypeID, func)).second == false)
{
//duplicate key!
ASSERT(false, L"Nooooo!");
}
}
No need for destructor or a count.
If your global objects are in separate DLL's(or shared libs) that are lazy loaded.
This may cause a problem similar to your description.
You are not setting the pointer back to null.
MessageAllocator::~MessageAllocator()
{
s_count--;
if (s_count == 0)
{
delete s_map;
s_map = 0;
}
}
Turns out that the object files containing the static initializers were not included by the linker because nothing referenced any functions in them. To work around this I extern "C"-ed one of the generated functions so that it would have a predictable non-mangled name and then forced a reference to it using a pragma like this for each message
#pragma comment(linker, "/include:Create_GraphicsDynamicMeshCreationMessage")
which I put in the generated header file that is later included in all the other non-generated files. It's MSVC only and kind of hack but I assume I can do something similar on GCC once I eventually port it.