_heapwalk reports _HEAPBADNODE, causes breakpoint or loops endlessly - c++

I use _heapwalk to gather statistics about the Process' standard heap.
Under certain circumstances i observe unexpected behaviours like:
_HEAPBADNODE is returned
some breakpoint is triggered inside _heapwalk, telling me the heap might got corrupted
access violation inside _heapWalk.
I saw different behaviours on different Computers. On one Windows XP 32 bit machine everything looked fine, whereas on two Windows XP 64 bit machines i saw the mentioned symptoms.
I saw this behaviour only if LowFragmentationHeap was enabled.
I played around a bit.
I walked the heap several times right one after another inside my program. First time doing nothing in between the subsequent calls to _heapWalk (everything fine). Then again, this time doing some stuff (for gathering statistics) in between two subsequent calls to _heapWalk. Depending upon what I did there, I sometimes got the described symptoms.
Here finally a question:
What exactly is safe and what is not safe to do in between two subsequent calls to _heapWalk during a complete heap walk run?
Naturally, i shall not manipulate the heap. Therefore i doublechecked that i don't call new and delete.
However, my observation is that function calls with some parameter passing causes my heap walk run to fail already. I subsequently added function calls and increasing number of parameters passed to these. My feeling was two function calls with two paramters being passed did not work anymore.
However I would like to know why.
Any ideas why this does not happen on some machines?
Any ideas why this only happens if LowFragmentationHeap is enabled?
Sample Code finally:
#include <malloc.h>
void staticMethodB( int a, int b )
{
}
void staticMethodA( int a, int b, int c)
{
staticMethodB( 3, 6);
return;
}
...
_HEAPINFO hinfo;
hinfo._pentry = NULL;
while( ( heapstatus = _heapwalk( &hinfo ) ) == _HEAPOK )
{
//doing nothing here works fine
//however if i call functions here with parameters, this causes
//_HEAPBADNODE or something else
staticMethodA( 3,4,5);
}
switch( heapstatus )
{
...
case _HEAPBADNODE:
assert( false );
/*ERROR - bad node in heap */
break;
...

Use HeapWalk, not _heapwalk.
Try locking the heap during your heap enumeration with HeapLock and HeapUnlock.
It certainly sounds like your function calls are modifying the Heap and invalidating the enumeration. Some vague advice, perhaps you can create a new Heap specifically for any memory needed by these function calls. This might require significant reworking of these static functions, I know.

Related

Memory leak when changing values of a C++ vector in a DLL

I am working on a C# plugin which calls a C++ DLL (with C wrapper in the DLL to do the link). In the C# program, I call several times the same method callMe of my DLL. In this method, I change values in a vector thermogram to perform others operations later.
Between each call, I try to free the memory because for now, at each call the RAM increase of 18 Mo so it is not good at all. I don't understand why because at each call, I just replace some values in an existing vector (2000 to be precise). So I tried to free the memory in different way (methods from vector class : erase, clear, shrink_to_fit) but nothing change the result. And all forums talk about these previous ways so I don't know what to try more.
C++ method :
bool MyClass::callMe(int pixel_value, int iImage)
{
if (thermogram.size() == 0) {
thermogram.resize(_nFrame - iFramesPass);
}
thermogram[iImage] = (double)pixel_value;
sizeThermo = iImage;
return true;
}
I also try not to clear between two calls, just to replace values at each new call, but the memory stll increase.
Maybe I miss something about calling a method from a DLL, or just I have a memory leak?

How to free allocated memory in a recursive function in C++

I have a recursive method in a class that computes some stages (doesn't matter what this is). If it notice that the probability of success for a stage is to low, the stage will be delayed by storing it in a queue and the program will look for delayed stage later. It grabs a stage, copies the data for working and deletes the stage.
The program runs fine, but I got a memory problem. Since this program is randomized it could happen that it delays up to 10 million stages which results in something like 8 to 12 GB memory usage (or more but it crashes before that happens). It seems the program never frees the memory for a deleted stage before reaching the end of the call stack of the recursive function.
class StageWorker
{
private:
queue<Stage*> delayedStages;
void perform(Stage** start)
{
// [long value_from_stage = (**start).value; ]
delete *start;
// Do something here
// Delay a stage if necessary like this
this->delayedStages.push(new Stage(value));
// Do something more here
// Look for delayed stages like this
Stage* front = this->delayedStages.front();
this->delayedStages.pop();
this->perform(&front);
}
}
I use pointer to pointer as I thought the memory is not freed, because there is a pointer (front*) that points to the stage. So I used a pointer that point to the pointer, and so I can delete it. But it seems not to work. If I watch the memory usage on Performance monitor (on Windows) it like like this:
I marked the end of the recursive calls. This is also just a example plot. real data, but in a very small scenario.
Any ideas how to free the memory of not longer used sages before reaching the end of the call stack?
Edit
I followed some advice and removed the pointers. So now it looks like this:
class StageWorker
{
private:
queue<Stage> delayedStages;
void perform(Stage& start)
{
// [long value_from_stage = start.value; ]
// Do something here
// Delay a stage if necessary like this
this->delayedStages.push(Stage(value));
// Do something more here
// Look for delayed stages like this
this->perform(this->delayedStages.front());
this->delayedStages.pop();
}
}
But this changed nothing, memory usage is the same as before.
As mentioned it maybe is a problem of monitoring. Is there a better way to check the exact memory usage?
Just to close this question as answered:
Mats Petersson (thanks a lot) mentiond in the comments that it could be a problem of monitoring the memory usage.
In fact this exactly was the problem. The code I provided in the edit (after replacing the pointers by references) frees the space correctly, but it is not given back to the OS (in this case Windows). So from the monitor it looks like the space is not freed.
But then I made some experiments and saw that freed memory is reused by the application, so it does not have to ask the OS for more memory.
So what the monitor shows is the maximum memory used bevore getting back the whole memory the recursive function required, after the first call of this function ends.

Seg fault on C++ map access

I've come across a strange issue in some code that I'm working on. Basically what's going on is that whenever I try to get some information from an empty map, the program segfaults. Here's the relevant code:
(note that struct Pair is a data structure that is defined earlier, and sendMasks is a std::map that is good)
std::map<std::string*, struct Pair*>::iterator it;
for(it = sendMasks->begin(); it != sendMasks->end(); it++){ //segfault
//(some code goes here)
}
I know that the pointer to the map is good; I can do
it = sendMasks->begin();
it = sendMasks->end();
before my loop, and it doesn't segfault at all then.
Now, if I put the following test before the for loop, it will segfault:
if( sendMasks->empty() )
As will any other attempt to determine if the map is empty.
This issue will only occur if the map is empty. My only thought on this issue would be that because I am updating sendMasks in a separate thread, that it may not have been updated properly; that however doesn't make any sense because this will only happen if the map is empty, and this code has worked perfectly fine before now. Any other thoughts on what could be happening?
EDIT:
I figured out what the problem was.
At an earlier part in my code, I was making a new char* array and putting that pointer into another array of length 4. I was then putting a NULL character at the end of my new array, but accidentally only did a subscript off of the first array - which went off the end of the array and overwrote a pointer. Somehow, this managed to work properly occasionally. (valgrind doesn't detect this problem)
The sequence was something like this:
object* = NULL; //(overwritten memory)
object->method();
//Inside object::method() :
map->size(); //segfault. Gets an offset of 0x24 into the object,
//which is NULL to begin with. memory location 0x24 = invalid
I wasn't expecting the instance of the object itself to be null, because in Java this method call would fail before it even did that, and in C this would be done quite differently(I don't do much object-oriented programming in C++)
If you are accessing a data structure from different threads, you must have some kind of synchronization. You should ensure that your object is not accessed simultaneously from different threads. As well, you should ensure that the changes done by one of the threads are fully visible to other threads.
A mutex (or critical section if on Windows) should do the trick: the structure should be locked for each access. This ensures the exclusive access to the data structure and makes the needed memory barriers for you.
Welcome to the multithreaded world!
Either:
You made a mistake somewhere, and have corrupted your memory. Run your application through valgrind to find out where.
You are not using locks around access to objects that you share between threads. You absolutely must do this.
I know that the pointer to the map is good; I can do
it = sendMasks->begin();
it = sendMasks->end();
before my loop, and it doesn't segfault at all then.
This logic is flawed.
Segmentation faults aren't some consistent, reliable indicator of an error. They are just one possible symptom of a completely unpredictable system, that comes into being when you have invoked Undefined Behaviour.
this code has worked perfectly fine before now
The same applies here. It may have been silently "working" for years, quietly overwriting bytes in memory that it may or may not have had safe access to.
This issue will only occur if the map is empty.
You just got lucky that, when the map is empty, your bug is evident. Pure chance.

Detect Incorrect stack variable usage

My application gives certain works to the worker agency to execute in a thread pool thread as given below
void Execute ProcessWork
{
int nRes = 0;
CFireProcessMessageWork *pProcessMessageWork = new CFireProcessMessageWork();
// Incorrect use of stack variable
pProcessMessageWork->m_pStatus = &nRes;
// Worker Agency
m_pMessageWorkerAgency->SubmitWork(pProcessMessageWork);
}
The definition of CFireProcessMessageWork is given below. The DoWork method of the class given below will be executed in a worker thread. Since the variable nRes is used in an improper way, my application crashes occasionally. I spent almost a week to identify the cause of the issue. I tried page heap with full options and Stack Frames (/RTCs) to detect the issue. But the application crashed at a location which has no relationship with the issue.
Is there any tools microsoft provides to detect these kind of issues?
class CFireProcessMessageWork
{
public:
int *m_pStatus;
public:
CFireProcessMessageWork()
{
m_pStatus = NULL;
}
int DoWork()
{
// Using Address of nRes
*mpStatus = 0;
// Do Some Work and Pass mpStatus to fill the error code
HRESULT hRes = pGEMMessageEvents->ProcessMessage(varData, m_nMsgCount, m_newTkt,m_idxFunc,&m_nRetVal);
return *mpStatus
}
}
The problem is that each one of those lines makes sense to the compiler. There is nothing wrong with them, and just the combination is not really good. Even then, it would require a good amount of extra work and analysis to determine that it is a wrong use.
Consider for example, that you could be joining the worker thread in the same function, and then everything would be correct, if the function did not process in a different thread but just manipulated the code in the SubmitWork call, then it would be correct... and the compiler does not necessarily know about threads, so the fact is that it is almost impossible for the compiler to detect this.
On the other hand, this is something that should be quite obvious to a reviewer, so it can be better tackled by reviewing code. Other possible options would be using some form of shared ownership to handle the resources --which might imply more cost:
void Execute ProcessWork {
std::shared_ptr<int> nRes = std::make_shared<int>( 0 );
CFireProcessMessageWork *pProcessMessageWork = new CFireProcessMessageWork();
pProcessMessageWork->m_pStatus = nRes; // copies the shared_ptr
m_pMessageWorkerAgency->SubmitWork(pProcessMessageWork);
}
In this case, the shared ownership of the object at the cost of an extra allocation, guarantees that the thread will not cause undefined behavior while updating the state. But while this will make the program correct from a language point of view, it might still be undesired: the status will not be readable outside of the worker thread, as the only other reference is outside of the worker control.
You are writing a syntactically valid code here by passing &nRes, however since it is a local varaible in stack and it is being accessed in some other thread, the address is not going to be valid, resulting in crash. I think a careful peer code review should help resolve such issues.

Side effects of exit() without exiting?

If my application runs out of memory, I would like to re-run it with changed parameters. I have malloc / new in various parts of the application, the sizes of which are not known in advance. I see two options:
Track all memory allocations and write a restarting procedure which deallocates all before re-running with changed parameters. (Of course, I free memory at the appropriate places if no errors occur)
Restarting the application (e.g., with WinExec() on Windows) and exiting
I am not thrilled by either solution. Did I miss an alternative maybe.
Thanks
You could embedd all the application functionality in a class. Then let it throw an expection when it runs out of memory. This exception would be catched by your application and then you could simply destroy the class, construct a new one and try again. All in one application in one run, no need for restarts. Of course this might not be so easy, depending on what your application does...
There is another option, one I have used in the past, however it requires having planned for it from the beginning, and it's not for the library-dependent programmer:
Create your own heap. It's a lot simpler to destroy a heap than to cleanup after yourself.
Doing so requires that your application is heap-aware. That means that all memory allocations have to go to that heap and not the default one. In C++ you can simply override the static new/delete operators which takes care of everything your code allocates, but you have to be VERY aware of how your libraries, even the standard library, use memory. It's not as simple as "never call a library method that allocates memory". You have to consider each library method on a case-by-case basis.
It sounds like you've already built your app and are looking for a shortcut to memory wiping. If that is the case, this will not help as you could never tack this kind of thing onto an already built application.
The wrapper-program (as proposed before) does not need to be a seperate executable. You could just fork, run your program and then test the return code of the child. This would have the additional benefit, that the operating system automatically reclaims the child's memory when it dies. (at least I think so)
Anyway, I imagined something like this (this is C, you might have to change the includes for C++):
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define OUT_OF_MEMORY 99999 /* or whatever */
int main(void)
{
int pid, status;
fork_entry:
pid = fork();
if (pid == 0) {
/* child - call the main function of your program here */
} else if (pid > 0) {
/* parent (supervisor) */
wait(&status); /* waiting for the child to terminate */
/* see if child exited normally
(i.e. by calling exit(), _exit() or by returning from main()) */
if (WIFEXITED(status)) {
/* if so, we can get the status code */
if (WEXITSTATUS(status) == OUT_OF_MEMORY) {
/* change parameters */
goto fork_entry; /* forking again */
}
}
} else {
/* fork() error */
return 1;
}
return 0;
}
This might not be the most elegant solution/workaround/hack, but it's easy to do.
A way to accomplish this:
Define an exit status, perhaps like this:
static const int OUT_OF_MEMORY=9999;
Set up a new handler and have it do this:
exit(OUT_OF_MEMORY);
Then just wrap your program with another program that detects this
exit status. When it does then it can rerun the program.
Granted this is more of a workaround than a solution...
The wrapper program I mentioned above could be something like this:
static int special_code = 9999;
int main()
{
const char* command = "whatever";
int status = system(command);
while ( status == 9999 )
{
command = ...;
status = system(command);
}
return 0;
}
That's the basicness of it. I would use std::string instead of char* in production. I'd probably also have another condition for breaking out of the while loop, some maximum number of tries perhaps.
Whatever the case, I think the fork/exec route mentioned below is pretty solid, and I'm pretty sure a solution like it could be created for Windows using spawn and its brethren.
simplicity rules: just restart your app with different parameters.
it is very hard to either track down all allocs/deallocs and clean up the memory (just forget some minor blocks inside bigger chunks [fragmentation] and you still have problems to rerun the class), or to do introduce your own heap-management (very clever people have invested years to bring nedmalloc etc to live, do not fool yourself into the illusion this is an easy task).
so:
catch "out of memory" somehow (signals, or std::bad_alloc, or whatever)
create a new process of your app:
windows: CreateProcess() (you can just exit() your program after this, which cleans up all allocated resources for you)
unix: exec() (replaces the current process completely, so it "cleans up all the memory" for you)
done.
Be warned that on Linux, by default, your program can request more memory than the system has available. (This is done for a number of reasons, e.g. avoiding memory duplication when fork()ing a program into two with identical data, when most of the data will remain untouched.) Memory pages for this data won't be reserved by the system until you try to write in every page you've allocated.
Since there's no good way to report this (since any memory write can cause your system to run out memory), your process will be terminated by the out of memory process killer, and you won't have the information or opportunity for your process to restart itself with different parameters.
You can change the default by using the setrlimit system call, to to limit the RLIMIT_RSS which limits the total amount of memory your process can request. Only after you have done this will malloc return NULL or new throw a std::bad_alloc exception when you reach the limit that you have set.
Be aware that on a heavily loaded system, other processes can still contribute to a systemwide out of memory condition that could cause your program to be killed without malloc or new raising an error, but if you manage the system well, this can be avoided.