C++ std::mutex lock() access violation in Visual Studio 2017 - c++

When I'm trying to run executable compiled using VS2017 I catch
Exception thrown at 0x00007FFF05BC1063 (msvcp140d.dll) in a.exe: 0xC0000005: Access violation reading location 0x0000000000000000. immediately after launching.
After debugging i figured out that it happens when I'm trying to lock static mutex _coutMutex. How can I fix it because when I have compiled using mingw it worked fine. Here is part of my code:
Game.hpp:
#include "Logger.hpp"
class Game
{
public:
static Logger logger;
};
Game.cpp:
#include "Game.hpp"
Logger Game::logger{ "logs/client", Logger::LoggingLevels::Info,
Logger::LoggingLevels::Trace, 2, 100 };
Logger.hpp:
#include <mutex>
class Logger
{
public:
Logger(std::string path, short consoleLoggingLevel, short
fileLoggingLevel, uint32_t count, size_t maxSize);
enum LoggingLevels : short
{
Off = 0,
Fatal = 1,
Error = 2,
Warn = 3,
Info = 4,
Debug = 5,
Trace = 6
};
void _addToQueue(std::string data);
private:
static std::mutex _coutMutex;
};
Logger.cpp:
std::mutex Logger::_coutMutex;
Logger::Logger(std::string path, short consoleLoggingLevel,
short fileLoggingLevel, uint32_t count, size_t maxSize)
{
_addToQueue("dd/mm/yyyy hh:mm:ss.sss\n");
}
void Logger::_addToQueue(std::string data)
{
_coutMutex.lock();
std::cout << data;
_coutMutex.unlock();
}
main.cpp:
#include "Logger.hpp"
#include "Game.hpp"
int main()
{
Game game;
}

As Richard Critten suggests, this must be the global initialisation order problem.
You have 2 global variables, logger and _coutMutex, and these are in a different compilation unit. The order which they are initialized is not defined.
When Logger's constructor runs, _coutMutex is not initialized yet, but _addToQueue wants to use it.
You could have three solutions:
Avoid using global objects. Or avoid using global constructors which do something serious (if you remove _addToQueue from logger constructor, it will work).
put these global variables into one compilation unit, in correct order
add an accessor function for _coutMutex, and define mutex inside of it (as a static variable). Beware of this solution, as it has its drawbacks (speed, thread safety)

Related

C++ composition without using the heap in embedded systems

I'm fairly new to C++, this is also my first post on here. I'm trying to use C++ in an embedded systems project so I can take the OOP approach. I'm using the AVR crosspack toolchain (AVR G++ compiler)
My problem is this:
From what i've read, the heap should not be used for dynamic memory allocation in embedded systems. In any case, there is no implementation for "new" in AVR G++ anyway. I'm using composition, starting with a USART driver (lets call it a service), and a logger (singleton pattern, and also a service).
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, however when I try to compose the objects needed in this way I get the following error:
Main/main.cpp: In function 'int main()':
Main/main.cpp:21:13: error: request for member 'log' in 'logSystem', which is of non-class type 'LogSystem(Usart)'
21 | logSystem.log("Hello");
| ^~~
make: *** [Main/main.o] Error 1
My sense is that my syntax for passing in an object as a constructor parameter is wrong, but I'm not sure what it should be as all the examples i can find use the "new" keyword in the constructor definition to create the object on the free store. Can anyone help?
The Code:
In "usart.h":
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
// Constructor and destructor
Usart();
~Usart();
// Initialisation routine
static void const init(void);
// Utility function to transmit a string
static void const print(const char myString[]);
};
In "logger.h":
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart usart);
~LogSystem();
Usart usart;
static void const log(char *msg);
};
In "logger.cpp"
#include "logger.h"
LogSystem::LogSystem(Usart usart)
{
Usart usart;
usart.init();
}
LogSystem::~LogSystem()
{
}
LogSystem::log(char *msg)
{
usart.print(msg);
}
In "main.cpp":
#include "logger.h"
int main()
{
LogSystem logSystem(Usart usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
[...] the heap should not be used for dynamic memory allocation in embedded systems.
It depends. I'm currently in an embedded project with maximum safety-related requirements, and we use new, but not delete. So we have a heap, but don't allocate "dynamically", because all allocated objects are kept during the runtime.
In any case, there is no implementation for "new" in AVR G++ anyway.
Is this true? I never checked... It might be necessary to provide a heap before being able to use new.
It's my understanding that services should have their dependancies passed in on instantiation using constructor parameters, [...]
This is a good idea. ;-) It helps unit-testing.
For your syntactical and design problems: This is how I would write your sources.
"usart.h":
All methods are non-static to have access to member variables.
The const attribute on a return type is doing nothing. Did you mean to declare the method constant? Then const belongs after the parameter list. However, this attribute might be wrong if such a method changes any member variable.
#include <avr/io.h>
#include <util/setbaud.h>
class Usart
{
public:
Usart();
~Usart();
void init(void);
void print(const char myString[]);
};
"logger.h":
Just give and store a reference to the USART to avoid a copy.
#include "usart.h"
class LogSystem
{
public:
LogSystem(Usart& usart);
~LogSystem();
void log(const char *msg);
private:
Usart& _usart;
};
"logger.cpp"
The member variable _usart is directly initialized in the constructor, before any statement is executed.
#include "logger.h"
LogSystem::LogSystem(Usart& usart) : _usart(usart)
{
_usart.init();
}
LogSystem::~LogSystem()
{
}
void LogSystem::log(const char *msg)
{
_usart.print(msg);
}
"main.cpp":
Provide the USART object on the stack, as the logger.
#include "logger.h"
int main()
{
Usart usart;
LogSystem logSystem(usart);
while(1)
{
logSystem.log("Hello");
}
return 0;
}
The singleton design pattern is deprecated since it was invented, because it is so hard to test. Simply use just one object or a limiting object factory.

Why does an exported dll class give me memory access violation in client program? [SOLVED]

So I've got this interface class that I include, both in the dll and the client project
// InterfaceClass.h
#pragma once
class InterfaceClass
{
public:
virtual void Update() = 0;
};
This is the dll class that calls one of its own methods inside update
// DLLClassThatDoesSomething.cpp
#include "InterfaceClass.h"
#include <iostream>
#include <string>
class __declspec(dllexport) DLLClass : public InterfaceClass
{
public:
void Update()
{
std::cout << this->GetString();
}
std::string& GetString()
{
std::string thestring = "bruhmoment";
return thestring;
}
};
extern "C"
{
__declspec(dllexport) InterfaceClass* CreateInstance()
{
return new DLLClass();
}
}
And this is the "Client" project
// main.cpp
#include "InterfaceClass.h"
#include <Windows.h>
typedef InterfaceClass* (__cdecl *Class) ();
int main()
{
HINSTANCE dll = LoadLibrary(L"DLLClass.dll");
Class klass = (Class)GetProcAddress(dll, "CreateInstance");
InterfaceClass* IKlass = klass();
IKlass->Update();
FreeLibrary(dll);
return 0;
}
The moment I call IKlass->Update() I get an exception for Access Memory Violation because of the DLLClass calling its own method.
I haven't tried anything since I barely know how to load a DLL on runtime and I've used this nifty tutorial
How can I let it call the method and not get thrown an exception? I'm trying to let ppl that will create mods for my game create their own mods with their custom classes for bosses, mobs and etc. in DLLs.
EDIT:
Turns out it was a syntax mistake on my end. Instead of return new DLLClass;, it had to be return new DLLClass();. After fixing it, it works as intended.
You return a reference to a local variable thestring, and by the time you try to access it in
std::cout << this->GetString(), referenced data is already destroyed. In fact, it is destroyed right after the end of enclosing scope of compound statement where the variable was declared.
It may "appear" to work sometimes due to the stack not being overwritten yet, but eventually it will fail miserably like it did in your case. This triggers UB (undefined behavior).

Undefined reference to static member function of a class in a namespace C++

I have created a C++ class to provide methods to manipulate mutex and it is supposed to work on Windows as well as Linux based systems. When I compile this code without enclosing the class in namespace, it compiles and works. But when I enclose it in a namespace, I get a compile time error for all static methods, following is example of one.
undefined reference to
`mutexns::MutexHandler::Down(pthread_mutex_t*)'
I have had no luck yet to use this class from within a namespace. Any and all suggestions will be much appreciated. Thank you in advance.
I am using g++ compiler on an Ubuntu 16.04 machine.
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
Following is the class definition which results in above mentioned compile time error.
#ifndef MUTEXHANDLER_H_
#define MUTEXHANDLER_H_
namespace mutexns
{
#ifdef WIN32
#include <windows.h>
#define MUTEX HANDLE
#else
#include <pthread.h>
#define MUTEX pthread_mutex_t
#endif
typedef enum
{
SUCCESS = 0, // Operation successful
ERR_UNKNOWN = -1, // An unknown error occurred
ERR_MUTEX_CREATION = -2, // Error creating mutex
ERR_MUTEX_LOCK = -3, // Error acquiring lock
ERR_MUTEX_UNLOCK = -4, // Error releasing lock
} MUTEX_ERROR;
class MutexHandler
{
private:
MutexHandler ();
public:
static MUTEX_ERROR
Initialize (MUTEX *mutex);
static MUTEX_ERROR
Down (MUTEX *mutex);
static MUTEX_ERROR
Up (MUTEX *mutex);
static MUTEX_ERROR
TryDown (MUTEX *mutex); // Only for Linux
};
}
#endif /* MUTEXHANDLER_H_ */

Calling Static Member Function causes runtime error

I am getting a runtime access violation error when defining a static class variable. I'm not quite sure what is exactly going wrong; is the static function I am calling not implemented at the time of calling, something else?
What is going wrong and how can I fix this?
Runtime error (see code below for the line that the error occurs on):
0xC0000005: Access violation reading location 0x00000000.
Code:
// Status.h
class Status
{
public:
// Static Properties//
static const Status CS_SUCCESS;
// Static Functions //
static const Status registerState(const tstring &stateMsg)
{
int nextStateTmp = nextState + 1;
auto res = states.emplace(std::make_pair(nextStateTmp, stateMsg));
return (res.second) ? Status(++nextState) : Status(res.first->first);
}
private:
static std::unordered_map<STATE, tstring> states;
static STATE nextState;
};
// Status.cpp
#include "stdafx.h"
#include "Status.h"
// Class Property Implementation //
State Status::nextState = 50000;
std::unordered_map<STATE, tstring> Status::states;
const Status S_SUCCESS = Status::registerState(_T("Success"));
// IApp.h
class IApp : protected Component
{
public:
static const Status S_APP_EXIT;
static const Status S_UNREGISTERED_EVT;
...
};
// IApp.cpp
#include "stdafx.h"
#include "../EventDelegate.h"
#include "../Component.h"
#include "IApp.h"
// Class Property Implementation //
const Status IApp::S_APP_EXIT = CStatus::registerState(_T("IApp exit")); // Runtime error: 0xC0000005: Access violation reading location 0x00000000.
const Status IApp::S_UNREGISTERED_EVT = CStatus::registerState(_T("No components registered for this event"));
Some static variables like S_APP_EXIT depend on other static variables (e.g. nextState) for their initialization.
Read about the static initialization order fiasco and fix your code accordingly (making nextState a private variable?). You might even think of using the Construct On First Use Idiom (explained in the other FAQ here).
Anyway I wouldn't generally advise keeping all those variables static, but it's quite hard to tell from just the excerpt you posted (where is CS_SUCCESS defined?).

C++ - Having problems defining a variable inside main() function

I am trying to define a variable from an external library in C++, Visual Studio 2010. It only works when I put it outside of the main function.
This code crashes:
#include "StdAfx.h"
#include <ogdf\basic\Graph.h>
#include <ogdf\basic\graph_generators.h>
int main()
{
ogdf::Graph g;
ogdf::randomSimpleGraph(g, 10, 20);
return 0;
}
It gives me an unhandheld exception: Access violation.
However, if it is outside main function, it works without any problem:
#include "StdAfx.h"
#include <ogdf\basic\Graph.h>
#include <ogdf\basic\graph_generators.h>
ogdf::Graph g;
int main()
{
ogdf::randomSimpleGraph(g, 10, 20);
return 0;
}
Do you have any how do I fix that? I assume, that it is caused by some kind of linking problem.
EDIT: It looks like the problem is not the initialization of the variable. It throws an exception, when the application exits.
int main()
{
ogdf::Graph g; // No problem
ogdf::randomSimpleGraph(g, 10, 20); // No problem
int i; // No problem
std::cin>>i; // No problem
return 0; // Throws an exception after read i;
}
Call stack:
The output is:
First-chance exception at 0x0126788f in graphs.exe: 0xC0000005: Access violation writing location 0x00000000.
Unhandled exception at 0x0126788f in graphs.exe: 0xC0000005: Access violation writing location 0x00000000.
Works on my machineā„¢.
Esoteric errors like that are often a result of binary incompability. Basically, because of different compiler/preprocessor options, effective headers that your code and the library "see" are different.
For instance, if you have a library with following header code:
class Foo
{
#ifdef FOO_DEBUG
int debug_variable;
#endif
int variable;
};
Library function:
void bar(Foo& foo)
{
std::cout << foo.variable;
}
And client code:
Foo foo;
foo.variable = 666;
bar(foo);
If FOO_DEBUG is not in sync amongst client and the library, this will possibly crash and burn -- variable will have different expected offset.
In your case, I suspect one of the following may be true:
You have built the ogdf with different compiler than your code
If not, you ogdf and your code have different build configurations (Release vs Debug)
Both are debug, but you have defined OGDF_DEBUG (as recommended here)
You have different "Struct Member Alignment" setting