EXC_BAD_ACCESS upon accessing a static member? - c++

I've developed a game on Cocos2d-x v2 platform
I started on Android, after completely finishing the coding on Eclipse I used the same code on Xcode to create and iOS version.
After adding all the required libraries, I succeeded in compiling the code. However, the game hangs the moment it runs on an iOS device, although it runs without any problem on Android.
I tried both the emulator and an iPod, but I always get an EXC_BAD_ACCESS when accessing a static member from a static method. The static member would always point to 0x0!!
Here's an excerpt from the code:\
AppDelegate.cpp
#include "AppDelegate.h"
#include "NASEncData.h"
AppDelegate::AppDelegate()
{
ep = NASEncData::sharedUserData();
}
NASEncData.h
namespace CocosNas
{
class NASEncData : public CCObject
{
public:
static NASEncData* sharedUserData();
private:
NASEncData();
static void initXMLFilePath();
static std::string m_sFilePath;
}
}
NASEncData.cpp
#include "NASEncData.h"
NASEncData* NASEncData::sharedUserData()
{
initXMLFilePath();
// only create xml file one time
// the file exists after the programe exit
if ((! isXMLFileExist()) && (! createXMLFile()))
{
return NULL;
}
if (! m_spUserData)
{
m_spUserData = new NASEncData();
}
return m_spUserData;
}
void NASEncData::initXMLFilePath()
{
if (! m_sbIsFilePathInitialized)
{
m_sFilePath += CCFileUtils::sharedFileUtils()->getWriteablePath() + NASENCDATA_XML_FILE_NAME; <----error happens here
m_sbIsFilePathInitialized = true;
}
}

Based on the comments on your question, your problem could be the initialization order of static data. To be more specific, I think it is possible that the static AppDelegate instance gets created and initialized before the static members in the NASEncData. And this problem could also explain the fact that you are seeing different behavior on different platform, because the initialization order of unrelated static data are compiler and linker dependent.
To fix this, you could change your NASEncData like this: (note that this is only one possible fix, although if the initialization order of statics is really your problem, I think this is the simplest and best solution, apart from redesigning your code so that you don't have to rely on static members.)
NASEncData.h
namespace CocosNas
{
class NASEncData : public CCObject
{
public:
static NASEncData* sharedUserData();
private:
NASEncData();
static void initXMLFilePath();
// Note how the stuff below this line have changed
struct StaticData
{
std::string m_sFilePath;
// Put other static members here
// (e.g. m_sbIsFilePathInitialized, m_spUserData, etc.)
// Put a proper constructor here if needed
};
static StaticData & getStaticData ()
{
static StaticData s_data;
return s_data;
}
}
}
NASEncData.cpp
void NASEncData::initXMLFilePath()
{
if (! m_sbIsFilePathInitialized)
{
// Note the change in accessing m_sFilePath
// You should access all your static members like this
getStaticData().m_sFilePath +=
CCFileUtils::sharedFileUtils()->getWriteablePath() +
NASENCDATA_XML_FILE_NAME;
getStaticData().m_sbIsFilePathInitialized = true;
}
}
What this does in ensure that when you try and access your static member data, they have already been initialized. This happens because all your static member data are now defined inside a function as static, and for accessing them you have to call that function, and the compiler generates code to make sure that the first time that function is invoked (and only the first time) your data is constructed and initialized properly, which in turn means that the first time you actually try to access this data, whenever and wherever that may be from, your data is properly initialized.

It was indeed an initialization problem I just had to move the code from the construction to bool AppDelegate::applicationDidFinishLaunching() and it worked!

Related

Why std::bad_cast exception in boost::locale::date_time for global but not local objects?

I'm having problems writing a wrapper class using the boost::locale::date_time library. Specifically, I cannot create a global object from my class, though everything works fine other than that.
Here's relevant sample code:
// DateTimeWrapper.h
#include <boost\\locale\\date_time.hpp>
#include <boost\\locale.hpp>
class DateTimeWrapper
{
public:
DateTimeWrapper();
~DateTimeWrapper();
// ... Other methods...
protected:
boost::locale::date_time* m_date_time;
static void Init_Global_Locale();
static bool m_Global_Locale_Initialized;
};
// DateTimeWrapper.cpp
bool DateTimeWrapper::m_Global_Locale_Initialized = false;
DateTimeWrapper::DateTimeWrapper()
{
Init_Global_Locale();
// The following line will work for the local object,
// but throws a std::bad_cast exception for the global object
m_date_time = new boost::locale::date_time;
}
DateTimeWrapper::~DateTimeWrapper()
{
delete m_date_time;
}
void DateTimeWrapper::Init_Global_Locale()
{
if (!m_Global_Locale_Initialized)
{
boost::locale::generator gen;
std::locale l = gen("");
std::locale::global(l);
m_Global_Locale_Initialized = true;
}
}
// This object throws a std::bad_cast exception. Code runs normally if I comment out the following line.
DateTimeWrapper global_date_time_object;
int main()
{
// This object works just fine
DateTimeWrapper local_date_time_object;
// Do stuff with local_date_time_object...
return(0);
}
As you can see in the code, I use a static member to make sure the global locale is initialized the first time a DateTimeWrapper object is created. Normally, this prevents a std::bad_cast exception from being thrown when I create my boost::locale::date_time member. However, I still receive the exception from that line when the first DateTimeWrapper object created is a global instance.
Note that stepping through the debugger, I can confirm that all lines in the Init_Global_Locale() method are run during construction of the global object. This sample code also declares DateTimeWrapper::m_Global_Locale_Initialized before it declares global_date_time_object, within the same source file, so I know that order-of-initialization is not the problem here (confirmed by stepping through with the debugger anyhow).
So why does the code work for local objects but not global objects, even though I can see all lines of code are run through, in the correct order, for both versions?
I cannot reproduce the error (with the code shown in a single TU).
My hunch is that you have void DateTimeWrapper::Init_Global_Locale() and m_Global_Locale_Initialized defined in another translation unit, which lands you in SIOF (static initialization order fiasco).
Besides, there are numerous complexities about your types inviting errors (using non-owned pointers, not following Rule-Of-Zero/Three/Five). I'd write it much simpler, using C++11's function local static initialization:
#include <boost/locale.hpp>
#include <boost/locale/date_time.hpp>
struct EnsureLocaleBase {
EnsureLocaleBase() { Init(); }
private:
static bool Init() {
static auto const s_init = [] {
boost::locale::generator gen;
std::locale l = gen("");
std::locale::global(l);
return true;
}();
return s_init;
}
};
class DateTimeWrapper : EnsureLocaleBase {
boost::locale::date_time m_date_time;
};
DateTimeWrapper global_date_time_object;
int main() {
DateTimeWrapper local_date_time_object;
}
Function local statics don't suffer SIOF and also are thread-safely initialized.

Hiding queryable program state without using a class?

Consider a library exporting a distinct interface for initialization, which has to be called by the user before using anything else the library provides. In this step, certain system state is queried and stored in corresponding variables. This cannot be mapped to constants, but should also not be prone to changes due to writes from external sources, i.e. the system state should be queryable in different translation units but not writable.
One obvious example is a timestamp marking the system startup. This cannot be a compile-time constant, but should also never be writable.
This could be realized with a class implementing only static functions and using private, static members:
// system.h
#include <chrono>
using sys_time_point = std::chrono::system_clock::time_point;
class System
{
public:
System () = delete;
// possibly other deleted functions
static bool init () noexcept;
static bool ready () noexcept;
static const sys_time_point& initTime() noexcept;
private:
static bool initState_;
static sys_time_point initTime_;
};
// system.cpp
bool System::initState_ = false;
sys_time_point System::initTime_ = std::chrono::system_clock::now();
The thing is, I consider the latter approach an inadequate design choice because the functions, although possibly dependent on each other, define more or less miscellaneous functionality for querying system state, not modifying or accessing private state of user-defined type.
I'd much rather go for the second approach. Suppose a namespace System which groups the same functionality as the prior class did
// System.h
#include <chrono>
namespace System
{
using sys_time_point = std::chrono::system_clock::time_point;
bool init () noexcept; // needs to be called
bool ready () noexcept; // can be used by other lib components and lib clients
const sys_time_point& initTime() noexcept; // returns system startup time point
// other stuff here ...
}
// System.cpp
namespace System
{
namespace
{
bool sysInitState = false;
sys_time_point sysInitTime = std::chrono::system_clock::now();
}
bool init() noexcept
{
// init code here ... set and return sysInitState accordingly
}
bool ready() noexcept
{
return sysInitState;
}
const sys_time_point& initTime() noexcept
{
return sysInitTime;
}
}
Using the unnamed namespace, I suppress linking to the variables externally in other translation units. AFAIK, there is no way to access them in other translation units except using the functions in namespace System. Writing is also not possible due to const refs or returns by value - except for the scenario where an evil programmer might const_cast<> the const refs to non-const refs.
My questions would now be:
is the above, second solution correct at all?
is the above, second solution viable?
are there other solutions which might be more safe or easier to implement?
Thanks everyone!
Obscuring the private information in a namespace works, but I recommend putting them in a struct and storing one copy of that struct in a local variable.
// System.cpp
namespace {
struct SysInit
{
bool state;
sys_time_point time;
SysInit()
: state(false)
, time (std::chrono::system_clock::now())
{ }
static SysInit& instance()
{
static SysInit rval;
return rval;
}
};
}
void init() noexcept
{
SysInit::instance().state = true;
}
bool ready() noexcept
{
return SysInit::instance().state;
}
const sys_time_point& initTime() noexcept
{
return SysInit::instance().time;
}
The reason for this peculiar trick is there is no order of initialization for globals in different .cpp files. If one of your user's .cpp files calls init() in your example before sysInitTime gets initialized, init may use bad values, or worse, the sysInitTime initializer might change its value, which your library doesn't want.
Static local variables are guaranteed to be initialized once, the first time a function gets called. By storing the data in a static local variable rather than a global, we ensure you have constructed values ready to work with. By putting them in a struct together with one function that returns the whole group, we make it easier on the developer to prove that they are all indeed constructed and up to date (not essential for the algorithm, but it makes it much easier to make sense of the code).
A similar pattern is used by boost, but instead of putting them in an anonymous namespace in a .cpp, they put the variables inside a namespace boost::detail. Boost openly states that if you start mucking around inside boost::detail undefined behavior can occur. They do this because many of their libraries are header only, and don't have a .cpp file to work with. I bring it up because having a detail namespace has become an accepted way of saying "no-touch" to implementation details.

How to initialize a static member object?

I didn't know that I didn't know this :) . and a similar question here didn't help much.
So here i am asking. Please Consider the following class:
//in Agent.h
class Agent : public ns3::Object{
private:
//...
static BaseWifi m_wifi;
//...
};
is this :
//Agent.cpp
BaseWifi temp;
BaseWifi Agent::m_wifi = temp;
very much different from this:
//Agent.cpp
BaseWifi Agent::m_wifi = BaseWifi();
The second approach doesn't work for me.
why and how?
I don't want to trouble you with more codes coz I faced this problem deep in my program. The program generate seg faults as things(members) inside BaseWifi's constructor are not initialized correctly. when those uninitialized internal members are used, seg faults occur.
Thank you in advance for your kind comments and answers.
p.s.:
In fact I found this issue when I hadn't yet initialized this static member and I was deleting an extra line :
BaseWifi temp;
in my main(), which added more to my confusion!!!(this one could be dependent on what I put in BaseWifi's constructor, so dont mind it for now)
Update-1:
For those who would like to see the BaseWifi:
class BaseWifi {
ns3::WifiHelper m_wifiHelper; // a wifi helper apply to setup vehicles Wifi
ns3::NqosWifiMacHelper m_wifiMacHelper; // a wifi mac helper apply to setup vehicles Wifi
ns3::YansWifiPhyHelper m_wifiPhyHelper; // a wifi phy helper apply to setup vehicles Wifi
std::string m_phyMode;
double m_rss; // -dBm
bool m_init_done;
public:
BaseWifi();
virtual void init();
ns3::NetDeviceContainer Install(ns3::NodeContainer &c);
virtual ~BaseWifi();
};
BaseWifi::BaseWifi() {
m_init_done = false;
m_rss = -80;
m_phyMode ="DsssRate1Mbps";
// TODO Auto-generated constructor stub
init();
}
void BaseWifi::init() {
NS_LOG_UNCOND("inside BaseWifi::init()");
m_wifiHelper.SetStandard (ns3::WIFI_PHY_STANDARD_80211b);
m_wifiPhyHelper = ns3::YansWifiPhyHelper::Default ();
// This is one parameter that matters when using FixedRssLossModel
// set it to zero; otherwise, gain will be added
m_wifiPhyHelper.Set ("RxGain", ns3::DoubleValue (0) );
// ns-3 supports RadioTap and Prism tracing extensions for 802.11b
m_wifiPhyHelper.SetPcapDataLinkType (ns3::YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
ns3::YansWifiChannelHelper wifiChannel;
wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
// The below FixedRssLossModel will cause the rss to be fixed regardless
// of the distance between the two stations, and the transmit power
wifiChannel.AddPropagationLoss ("ns3::FixedRssLossModel","Rss",ns3::DoubleValue (m_rss));
m_wifiPhyHelper.SetChannel (wifiChannel.Create ());
// Add a non-QoS upper mac, and disable rate control
m_wifiMacHelper = ns3::NqosWifiMacHelper::Default ();
m_wifiHelper.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
"DataMode",ns3::StringValue (m_phyMode),
"ControlMode",ns3::StringValue (m_phyMode));
// Set it to adhoc mode
m_wifiMacHelper.SetType ("ns3::AdhocWifiMac");
m_init_done = true;
}
//Install the class's embedded settings on the nodes in this node container.
ns3::NetDeviceContainer BaseWifi::Install(ns3::NodeContainer &nc) {
return m_wifiHelper.Install(m_wifiPhyHelper, m_wifiMacHelper, nc);
}
I have run into these kind of issues before. Apparently the initialization of static member objects very much depends on where the implementation is done in your code and (probably) on how the whole thing is compiled. The solution that I found (somewhere) to the problem was to wrap the whole thing into a static member function like this:
//in Agent.h
class Agent : public ns3::Object{
private:
//...
static BaseWifi& m_wifi();
//...
};
and:
//in Agent.cpp
BaseWifi& Agent::m_wifi() {
static BaseWifi TheObject=BaseWifi();
return TheObject;
}
This way the object is initialized properly the first time the static member function is called.
The difference here is the first approach is using copy constructor to initialize the object while the second is using the default constructor.

Segfaults with singletons

// Non singleton
class MyLogManager
{
void write(message) {Ogre::LogManager::getSingletonPtr()->logMessage(message);}
}
class Utils : public singleton<Utils>
{
MyLogManager *handle;
MyLogManager& getHandle { return *handle; }
};
namespace someNamespace
{
MyLogManager &Log() { return Utils::get_mutable_instance().getHandle(); }
}
int main()
{
someNamespace::Log().write("Starting game initializating...");
}
In this code I'm using boost's singleton (from serialization) and calling Ogre's log manager (it's singleton-type too).
The program fails at any trying to do something with Ogre::LogManager::getSingletonPtr() object with code
User program stopped by signal (SIGSEGV)
I checked that getSingletonPtr() returns address 0x000
But using code Utils::get_mutable_instance().getHandle().write("foo") works good in another part of program. What's wrong could be there with calling singletons?
Real version of Utils class:
class Utils : public singleton<Utils>
{
protected:
ConfigManager *configHandlePtr;
LogManager *logHandlePtr;
public:
Utils()
{
configHandlePtr = new ConfigManager();
string engineLog = configHandle().getValue<string>("engine.logFilename", "Engine.log");
logHandlePtr = new LogManager(engineLog);
}
~Utils()
{
delete configHandlePtr;
delete logHandlePtr;
}
ConfigManager &configHandle() const { return *configHandlePtr; }
LogManager &logHandle() const { return *logHandlePtr; }
};
And here is the real code of LogManager class:
class LogManager
{
protected:
string mDefaultPath;
public:
LogManager(const string &logPath = "Engine.log") :
mDefaultPath(logPath) { }
void write(const string &message, const string logFile = "")
{
string workPath = mDefaultPath;
Ogre::LogManager *logHandle = Ogre::LogManager::getSingletonPtr(); // [logHandle=0x000]
Ogre::Log *log2Handle = logHandle->getLog(workPath); // [SEGFAULT]
log2Handle->logMessage(message);
Ogre::LogManager::getSingletonPtr()->logMessage(message);
}
};
UPDATE:
I have a static library (there is my engine code) and the main own programm which links static this library. When I call my config handle (which doesn't use Ogre) everything is okay! There is also resourceManager, it uses Ogre too. And it fails like logManager. Both this managers uses Ogre's singleton. Maybe it's impossible to call it from another library?
It feels like you have typical "static initialization order fiasco" - your Utils instance created before one (or both) of other singletons.
Try change Utils::configHandle() to something like this:
ConfigManager &configHandle() const {
static std::auto_ptr<ConfigManager> configHandlePtr(0);
if (!configHandlePtr.get()) {
configHandlePtr.reset(new ConfigManager());
// init configHandlePtr like you want
}
return *configHandlePtr;
}
I don't know Boost's singleton, but I notice some strange things in your 'Utils' class.
First of all, getHandle returns a reference to handle, but handle is a local variable that goes out of scope if you leave the method, so the reference to it will also be invalid.
Second, you didn't initialize handle in the getHandle method.
Are you sure your Ogre LogManager is correctly initialized?
Or maybe with your libraries you have one instance of the singleton in each library and only the one in your main program is correctly initialized?
In this case you have to declare the singletons in your libraries as "extern" but I'm not sure it applies to statically linked libraries.

Static vs. member variable

For debugging, I would like to add some counter variables to my class. But it would be nice to do it without changing the header to cause much recompiling.
If Ive understood the keyword correctly, the following two snippets would be quite identical. Assuming of course that there is only one instance.
class FooA
{
public:
FooA() : count(0) {}
~FooA() {}
void update()
{
++count;
}
private:
int count;
};
vs.
class FooB
{
public:
FooB() {}
~FooB() {}
void update()
{
static int count = 0;
++count;
}
};
In FooA, count can be accessed anywhere within the class, and also bloats the header, as the variable should be removed when not needed anymore.
In FooB, the variable is only visible within the one function where it exists. Easy to remove later. The only drawback I can think of is the fact that FooB's count is shared among all instances of the class, but thats not a problem in my case.
Is this correct use of the keyword? I assume that once count is created in FooB, it stays created and is not re-initialized to zero every call to update.
Are there any other caveats or headsup I should be aware of?
Edit: After being notified that this would cause problems in multithreaded environments, I clarify that my codebase is singlethreaded.
Your assumptions about static function variables are correct. If you access this from multiple threads, it may not be correct. Consider using InterlockedIncrement().
What you really want, for your long term C++ toolbox is a threadsafe, general purpose debug counters class that allows you to drop it in anywhere and use it, and be accessible from anywhere else to print it. If your code is performance sensitive, you probably want it to automatically do nothing in non-debug builds.
The interface for such a class would probably look like:
class Counters {
public:
// Counters singleton request pattern.
// Counters::get()["my-counter"]++;
static Counters& get() {
if (!_counters) _counters = new Counters();
}
// Bad idea if you want to deal with multithreaded things.
// If you do, either provide an Increment(int inc_by); function instead of this,
// or return some sort of atomic counter instead of an int.
int& operator[](const string& key) {
if (__DEBUG__) {
return _counter_map.operator[](key);
} else {
return _bogus;
}
}
// you have to deal with exposing iteration support.
private:
Counters() {}
// Kill copy and operator=
void Counters(const Counters&);
Counters& operator=(const Counters&);
// Singleton member.
static Counters* _counters;
// Map to store the counters.
std::map<string, int> _counter_map;
// Bogus counter for opt builds.
int _bogus;
};
Once you have this, you can drop it in at will wherever you want in your .cpp file by calling:
void Foo::update() {
// Leave this in permanently, it will automatically get killed in OPT.
Counters::get()["update-counter"]++;
}
And in your main, if you have built in iteration support, you do:
int main(...) {
...
for (Counters::const_iterator i = Counters::get().begin(); i != Countes::get().end(); ++i) {
cout << i.first << ": " << i.second;
}
...
}
Creating the counters class is somewhat heavy weight, but if you are doing a bunch of cpp coding, you may find it useful to write once and then be able to just link it in as part of any lib.
The major problems with static variables occur when they are used together with multi-threading. If your app is single-threaded, what you are doing is quite correct.
What I usually do in this situation is to put count in a anonymous namespace in the source file for the class. This means that you can add/remove the variable at will, it can can used anywhere in the file, and there is no chance of a name conflict. It does have the drawback that it can only be used in functions in the source file, not inlined functions in the header file, but I think that is what you want.
In file FooC.cpp
namespace {
int count=0;
}
void FooC::update()
{
++count;
}