Recently I got a segfault when reading atomic counters via glMapBuffer. Here is the code:
GLuint atomicCounter[2];
inline void getAtomicCounters()
{
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, ATOMIC_COUNTER_INDEX, acBuffer);
CHECK_FOR_GL_ERRORS();
static GLuint* data = (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY);
CHECK_FOR_GL_ERRORS();
atomicCounter[0] = data[0];
atomicCounter[1] = data[1];
glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
CHECK_FOR_GL_ERRORS();
}
The problem seems to be that data is a static pointer. When I remove the static keyword, everything works perfectly. I know that I don't need a static pointer, it was just a test and I'm quite surprised that it won't work with a static pointer. Does anybody know why a segfault occurs at "atomicCounter[0] = data[0];"?
This is not at all surprising.
Do you understand how a variable declared with the static qualifier in the body of a function works in C++? It will be initialized with that value the first time the function (getAtomicCounters (...)) runs, but each subsequent execution will skip-over the initialization:
static GLuint* data =
(GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_READ_ONLY);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//This is only evaluated the first time you call this function!
So every subsequent call is going to use the value of data you initialized the first time. The elephant in the room is that the value of data became invalid when you made this call: glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
You can fix this simply by assigning data the return value of glMapBuffer (...) on a separate line from the one where you declare the variable. Then it will always execute glMapBuffer (...) when you call this function.
However, to be completely honest, I can see no reason why you would need or even want static storage for your data pointer.
Related
Greetings fellow programmers.
I've been struggeling with learning c++ within the Unreal engine. I thought I understood how to track time properly within a class but alas my variable is chaning it's contents to a vastly different number in the time between two function calls.
For context there are a small number of objects present:
Global Time system
This class is responsible for managing the time and receiving update ticks from the time watcher. This is also a singleton!
TimeWatcher
Super simple, just a Uobject I spawn into the world so it can receive update ticks from the engine and pass them onto the Global Time system
Time class
A class to hold the hours, minutes and seconds. How it is used beyond that is up to the developer using the class. In my case I am simply trying to store it and from that point on remove time off of it to create a countdown timer.
We have our own little logging system to help debugging along, mainly to generate logs without all the unreal stuff and in a format we prefer. This log outputs the following data:
<Log, TimerSystem> [2] 2019.03.17-17.41.42: init attempt, init time should be: 23:6.0
<Log, TimerSystem> [3] 2019.03.17-17.41.42: init attempt succes, 23:6.0
<Log, TimerSystem> [6] 2019.03.17-17.41.42: Timer tick occured, lets see what our timer thinks about the time -225161083:32766:00
So from this we can interpret that the variable in the scope it gets set in(shown below) is set there properly. But the moment we try to read it again in the handleTick function the variable is all wrong.
InitTimer function:
void GlobalTimerSystem::InitTimer(UWorld* world, Time* initialTime)
{
DebugUtility::WriteLog("init attempt, init time should be: " + initialTime->ToString(), DebugUtility::Log, DebugUtility::TimerSystem);
check(world);
//create timeWatcher in the world
FVector location(0.0f, 0.0f, 0.0f);
FRotator rotation(0.0f, 0.0f, 0.0f);
FActorSpawnParameters SpawnInfo;
world->SpawnActor<ATimeWatcher>(location, rotation, SpawnInfo);
//set current time to init value
Time* trPointer = new Time(initialTime->GetHours(), initialTime->GetMinutes(), initialTime->GetSeconds());
this->timeRemaining = *trPointer;
DebugUtility::WriteLog("init attempt succes, " + timeRemaining.ToString(), DebugUtility::Log, DebugUtility::TimerSystem);
}
There is some stupid pointer crap I am doing here, partly because of desperation at this point though.
The Handle tick function:
void GlobalTimerSystem::HandleTimerTick(float deltaTime)
{
DebugUtility::WriteLog("Timer tick occured, lets see what our timer thinks about the time " + timeRemaining.ToString(), DebugUtility::Log, DebugUtility::TimerSystem);
ticksReceived++;
FString debug2;
debug2.Append("Ticks received: ");
debug2.AppendInt(ticksReceived);
DebugUtility::WriteLog(debug2, DebugUtility::Log, DebugUtility::TimerSystem);
double t = static_cast<double>(deltaTime);
DecreaseTimer(&t);
if (deltaTime != NULL) {
FString debug;
debug.Append(TEXT("current time remaining is "));
debug.Append(*timeRemaining.ToString());
DebugUtility::WriteLog(debug, DebugUtility::Log, DebugUtility::TimerSystem);
}
}
Now we know things are already wrong the moment we enter the above function. For good measure here is the header file for this class.
class PGT_PROJECT_API GlobalTimerSystem
{
friend class ATimeWatcher;
private:
Time timeRemaining;
Time timeElapsedNotPaused;
Time timeElapsedPaused;
UINT ticksReceived = 0;
bool paused = false;
bool initComplete = false;
void HandleTimerTick(float deltaTime);
static GlobalTimerSystem* timerSystem;
public:
static GlobalTimerSystem* GetTimerSystem();
void InitTimer(UWorld* world, Time* initialTime);
void IncreaseTimer(double* additionalSeconds);
void DecreaseTimer(double* removeSeconds);
double GetTimeRemaining();
double GetTimeElapsed();
GlobalTimerSystem();
~GlobalTimerSystem();
};
If any more information is required I will be happy to provide. Thank you for your time!
EDIT:
I am overloading the Time::operator= which appears as follows:
Time & Time::operator=(Time & t)
{
_seconds = t._seconds;
_minutes = t._minutes;
_hours = t._hours;
return *this;
}
And using it as follows:
this->timeRemaining = Time(initialTime->GetHours(), initialTime->GetMinutes(), initialTime->GetSeconds());
However this results in the following compiler error that I do not understand:
Path...\Private\GlobalTimerSystem.cpp(62) : error C4239: nonstandard extension used: 'argument': conversion from 'Time' to 'Time &'
In GlobalTimerSystem::InitTimer(UWorld*, Time*), you do the following:
Time* trPointer = new Time(initialTime->GetHours(),
initialTime->GetMinutes(),
initialTime->GetSeconds());
this->timeRemaining = trPointer;
which means:
Create a new object of type Time on the heap, construct it with the following arguments and, once it's ready, return a pointer to it (Time*) which I'll store in my local variable trPointer;
assign the value of the pointer trPointer (which is the address of the instance of the class Time that we just allocated and initialized on the heap) to my instance variable timeRemaining (which is an instance of the class Time).
So once you reach GlobalTimerSystem::HandleTimerTick, this->timeRemaining contains garbage which stays garbage when translated ToString (hence the -225161083:32766:00 you see). Furthermore, the memory you now have allocated on the heap for that instance of Time you've created is wasted as you will never release it and won't even use it.
The thing is that, in this case, you don't need the heap at all!
Depending on how operator= behaves (you said you overloaded it), you should be able to do:
this->timeRemaining = Time(initialTime->GetHours(),
initialTime->GetMinutes(),
initialTime->GetSeconds());
which will create a temporary Time instance and initialize it with the passed arguments, then "copy" it (=) inside your instance variable timeRemaining. If you do this, you might want to look into Time::operator=(Time&&) as that "temporary Time instance" is an rvalue. Please note that, in this case, we do not leak memory as everything is allocated on the stack and will be released when the function returns.
If this does not work, that means Time::operator= is not behaving as a proper "copy operator" and should be fixed. Another approach would be to manually set the hours, minutes and seconds fields of timeRemaining (if they are public or friend) or (much better), to have a method such as Time::set(/*hours, minutes, seconds*/) allowing you to this->timeRemaining->set(...).
Finally, once again depending on the internals of Time and how Time::operator= has been written, noticing that initialTime is itself a Time*, the "temporary intermediate Time instance" shouldn't even be needed, leading to the much simpler and more readable
this->timeRemaining = *initialTime;
As a conclusion, I believe your issue comes from the implementation of Time::operator=.
I have this method:
bool CDemoPickerDlg::IsStudentTalk(CString strAssignment)
{
bool bStudentTalk = false;
CString strTalkMain, strTalkClass;
if (theApp.UseTranslationINI())
{
strTalkMain = theApp.GetSMMethod(_T("IDS_STR_HISTORY_TALK_MAIN"));
strTalkClass = theApp.GetSMMethod(_T("IDS_STR_HISTORY_TALK_AUX"));
}
else
{
strTalkMain.LoadString(IDS_STR_HISTORY_TALK_MAIN);
strTalkClass.LoadString(IDS_STR_HISTORY_TALK_AUX);
}
int iTalkMainLen = strTalkMain.GetLength();
int iTalkClassLen = strTalkClass.GetLength();
if (strAssignment.Left(iTalkMainLen) == strTalkMain ||
strAssignment.Left(iTalkClassLen) == strTalkClass)
{
bStudentTalk = true;
}
return bStudentTalk;
}
It is called multiple times. Without added "member variables" to the class to cache values is there any other way to create the values for the two CString and int values just the once? As they will not change for the duration of the program.
The method above is static. I know about assigning a value to a static variable but I understand that can only be done once at the time of declaration. Have I miss-understood that?
You can use a static constant (or variable, but why make it variable if it isn't supposed to be changed?) at function scope:
static CString const someImmutableText = <some initializer>;
The placeholder <some initializer> above can be a literal, a function call or any other expression that you can initialize a CString from. The static makes sure the object is only created once and subsequently only initialized once, too.
#Ulrich's answer will of course work fine, but if <some initializer> is non-trivial there is a hidden downside - as of C++11, the compiler is required to generate a threadsafe initialiser.
This has minimal runtime overhead but it does generate quite a lot of code, see at Godbolt, and if you have a lot of these then this can add up.
If there are no multi-threading issues (which generally there aren't, especially in initialisation code), then there is a simple alternative which will eliminate this code. In fact, it's so simple that it's barely worth posting at all, but I'll do it here anyway for completeness. It's just this; please excuse the anglicisms:
static bool initialised;
static Foo *initialise_me;
static Bar *initialise_me_too;
...
if (!initialised)
{
initialise_me = new Foo (...);
initialise_me_too = new Bar (...);
...
initialised = true;
}
...
Note that the variables to be initialised are declared as raw pointers here and allocated with new. This is done for a reason - the one thing you most definitely don't want is to call constructors at the point where you declare these variables, else you'll be right back where you started. There are no object lifetime issues because the variables remain in existence for the entire duration of the program, so it's all good.
And, in fact, you don't actually need that bool at all - just test (say) initialise_me against nullptr.
I wonder, is the marked line in the below code correct. Because in this line the result of the function is assigned to the static variable prevRecCallResult (I'll call it "plain assignment"), which is changed inside this function (I'll call it "inside assignment").
Is it guaranteed, that the "inside assignment" is done, when the "plain assignment" executes?
int f(int _n)
{
if (_n >= 1)
{
static int prevRecCallResult;
prevRecCallResult = f(_n - 1); //<-- Is this line Ok?
return prevRecCallResult + 1;
}
else
return _n;
}
I know, the standard says, that a sequence point occurs:
At a function return, after the return value is copied into the
calling context.
, but I'm not sure, this is the answer to my question.
Update:
Considering replies I've received, I should clarify my question:
It's essence is: Is it true, that the prevRecCallResult is not in use by the assignment expression (in marked line) (i.e. is not occupied by it) until f(_n - 1) is finished? (And thus, until this moment, prevRecCallResult is absolutely free for any assignments inside f(_n - 1)?)
static int prevRecCallResult;
prevRecCallResult = f(_n - 1); //<-- Is this line Ok?
Your code is perfectly OK. But just wanted to make you remember that static int prevRecCallResult; executes only once. But prevRecCallResult = f(_n - 1); is assigned after each function call. Once function return prevRecCallResult's at time function's return value will be used in rest of the function.
One more thing, static variable will not die, after you return from function. So prevRecCallResult will not die across function calls.
As I remember all static variables as well as all global variables in C and C++ are assigned automatically to default value for their types - in this particular example default value for 'static int prevRecCallResult' will be 0. So your fears are unfounded (you can easily check this with debugger).
At the same time I cannot understand why you use static variable in this code... is it just simplified code for question or is it real code where you trying to economize memory on automatic variable of recursive function?
I have some small helper functions needed throughout the code.
To work, they need to be initialized with some data once.
Where should I store the init data?
I've come up with two methods:
I create static variables in the scope of the helper.cpp file which I set with a dedicated setter function and then use in my helper function.
static int _initData = 0;
void initHelpMe(int initData)
{
_initData = initData;
}
void helpMe()
{
doSomethingWith(_initData);
}
Or I use a static function variable inside the original helper function and a default parameter to it.
void helpMe(int initData = 0)
{
static int _initData = 0;
if (initData != 0)
_initData = initData;
doSomethingWith(_initData);
}
(Lets asume that 0 is outside of the valid data range of initData and that I've not shown additional code to ensure an error is raised when the function is called for the first time without initiating it first.)
What are the advantages / disadvantages of those two methods and is there an even better way of doing it?
I of course like the second method, because it keeps all the functionality in one place. But I already know it is not thread-safe (which is not an issue a.t.m.).
And, to make this more interesting, albeit being C++ this is not to be used in object-oriented but in procedural code. So please no answers proposing objects or classes. Just imagine it to be C with the syntax of C++.
I was going to suggest that you wrap your data into an object, until I realized that you are asking for a C solution with a C++ tag...
Both of your solutions have their benefits.
The second one is the one I'd prefer, assuming we just go by "what it looks like/maintainability". However, there is a drawback if helpMe is called MANY times with initData == 0, because of the extra if, which isn't present in the first case. This may or may not be an issue if doSomethingWith() is long enough a function and/or the compiler has the ability to inline helpMe (and initData is constant).
And of course, something in the code will have to call initHelpMe too, so it may turn out to be the same anyway.
In summary: Prefer the second one, based on isolation/encapsulation.
I clearly prefer the second! Global static data in different compilation units are initialized in unspecified order (In one unit in order, though). Local static data of a function is initialized at first call.
Example:
If you have two translation units A and B. The unit A calls during initialization the function helpMe of unit B. Assume the order of initialization is A, B.
The first solution will set the zero initialized _initData to some initData. After that the initialization of unit B resets _initData back to zero and may produce a memory leak or other harm.
There is a third solution:
void helpMe(int initData = 0)
{
static std::once_flag once;
static int _initData = 0;
std::call_once(once, [&] {
_initData = initData;
}
doSomethingWith(_initData);
}
I feel strongly both ways.
Prefer option 2 for the isolation, but option 1 lends itself to porting to a C++ class. I've coded both ways. It comes down to the SW architecture.
Let me offer another point.
Both options down side: You have not limited initialization to one occurrence. "need to be initialized with some data once". It appears OP's conditions insure a proper initialization of initHelpMe(123) or HelpMe(123) followed by helpMe(), but do not prevent/detect a secondary initialization.
Should a secondary need to be prevented/detected, some additional code could be used.
// Initialization
if (_initData != 0) {
; // Handle error
}
_initData = initData;
Another paradigm I've used follows. It may not be realizable in you code as it does not pass initData as a parameter but magically can get it.
void helpMe(void) {
static int Initialized = 0;
if (!Initialized) {
Initialized = 1;
_initData = initData();
}
doSomethingWith(_initData);
}
I have a very simple class that looks as follows:
class CHeader
{
public:
CHeader();
~CHeader();
void SetCommand( const unsigned char cmd );
void SetFlag( const unsigned char flag );
public:
unsigned char iHeader[32];
};
void CHeader::SetCommand( const unsigned char cmd )
{
iHeader[0] = cmd;
}
void CHeader::SetFlag( const unsigned char flag )
{
iHeader[1] = flag;
}
Then, I have a method which takes a pointer to CHeader as input and looks
as follows:
void updateHeader(CHeader *Hdr)
{
unsigned char cmd = 'A';
unsigned char flag = 'B';
Hdr->SetCommand(cmd);
Hdr->SetFlag(flag);
...
}
Basically, this method simply sets some array values to a certain value.
Afterwards, I create then a pointer to an object of class CHeader and pass it to
the updateHeader function:
CHeader* hdr = new CHeader();
updateHeader(hdr);
In doing this, the program crashes as soon as it executes the Hdr->SetCommand(cmd)
line. Anyone sees the problem, any input would be really appreciated
When you run into a crash, act like a crime investigator: investigate the crime scene.
what is the information you get from your environment (access violation? any debug messages? what does the memory at *Hdr look like? ...)
Is the passed-in Hdr pointer valid?
Then use logical deduction, e.g.:
the dereferencing of Hdr causes an access violation
=> passed in Hdr points to invalid memory
=> either memory wasn't valid to start with (wrong pointer passed in), or memory was invalidated (object was deleted before passing in the pointer, or someone painted over the memory)
...
It's probably SEGFAULTing. Check the pointers.
After
your adding some source code
your comment that the thing runs on another machine
the fact that you use the term 'flag' and 'cmd' and some very small datatypes
making me assume the target machine is quite limited in capacity, I suggest testing the result of the new CHeader for validity: if the system runs out of resources, the resulting pointer will not refer to valid memory.
There is nothing wrong with the code you've provided.
Are you sure the pointer you've created is the same same address once you enter the 'updateHeader' function? Just to be sure, after new() note the address, fill the memory, sizeof(CHeader), with something you know is unique like 0XDEAD, then trace into the updateHeader function, making sure everything is equal.
Other than that, I wonder if it is an alignment issues. I know you're using 8 bit values, but try changing your array to unsigned ints or longs and see if you get the same issue. What architecture are you running this on?
Your code looks fine. The only potential issue I can see is that you have declared a CHeader constructor and destructor in your class, but do not show the implementation of either. I guess you have just omitted to show these, else the linker should have complained (if I duplicate this project in VC++6 it comes up with an 'unresolved external' error for the constructor. It should also have shown the same error for the destructor if you had a... delete hdr; ...statement in your code).
But it is actually not necessary to have an implementation for every method declared in a class unless the methods are actually going to get called (any unimplemented methods are simply ignored by the compiler/linker if never called). Of course, in the case of an object one of the constructor(s) has to be called when the object is instantiated - which is the reason the compiler will create a default constructor for you if you omit to add any constructors to your class. But it will be a serious error for your compiler to compile/link the above code without the implementation of your declared constructor, so I will really be surprised if this is the reason for your problem.
But the symptoms you describe definitely sounds like the 'hdr' pointer you are passing to the updateHeader function is invalid. The reason being that the 1st time you are dereferencing this pointer after the updateHeader function call is in the... Hdr->SetCommand(cmd); ...call (which you say crashes).
I can only think of 2 possible scenarios for this invalid pointer:
a.) You have some problem with your heap and the allocation of memory with the 'new' operator failed on creation of the 'hdr' object. Maybe you have insufficient heap space. On some embedded environments you may also need to provide 'custom' versions of the 'new' and 'delete' operator. The easiest way to check this (and you should always do) is to check the validity of the pointer after the allocation:
CHeader* hdr = new CHeader();
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
The normal behaviour when 'new' fails should actually be to throw an exception - so the following code will cater for that as well:
try{
CHeader* hdr = new CHeader();
} catch(...) {
//handle or throw specific exception i.e. AfxThrowMemoryException() for MFC
}
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
}
b.) You are using some older (possibly 16 bit and/or embedded) environment, where you may need to use a FAR pointer (which includes the SEGMENT address) for objects created on the heap.
I suspect that you will need to provide more details of your environment plus compiler to get any useful feedback on this problem.