How do I determine how much stack and heap space my C++ program compiled with vs2012 uses?

I think I may have a heap of stack overflow problem in my code: is there a way to determine the maximum amount of stack space each thread in my code uses?

My code is native MFC C++ code (not .net code) compiled with Visual Studio 2012.

Thanks,

Chris
Christopher ScheneSystem Engineer/Software EngineerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
Teh stack size is determined when 'CreateThread()' is called, when you provide '0' as the stack size argument, the default is used, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms686774%28v=vs.85%29.aspx ("Thread Stack Size").

If you are thinking about the current stack usage, that'd only be able by using some odd tricks like reading ESP and comparing the address of your 1st local variable to it...

To determine the cause for that, I'd rather run your code under the debugger and set 'EXCEPTION_STACK_OVERFLOW' to 'Break when thrown' in "Debug|Exceptions...".
0
Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
I don't see a "createThread" call any place explicitly in my code.

Is that possibly something that is automatically done by the MFC framework?
0
Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
I did find a create thread, but my initial question is really the one I need an answer to: How much stack I am using. I really don't want to do it by trial and error and wait until the stack overflows as I am really curious as to how close to "full" I am approaching.
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
Hello: Any ideas as to how I can determine stack size.
0
dpearsonCommented:
Hey Chris,

I don't have any great insight for you other than to say I tried to find a profiling tool that could report this for me in a Java application and eventually had to give up the search.

I do think profilers are your best bet as this would need to be determined dynamically at runtime as you exercised the app.  There may be better tools in the C++ space - but when I looked for this exact thing in Java land I couldn't find it.

My approach ultimately was to just run manual experiments - setting the max thread size to <n>, run the app, see if it looked stable, if so reduce by 25% and repeat.  Once I found the rough limit this way, I then raised it back up a couple of notches to give myself a decent cushion.

FYI - if you take this approach you will also want to make sure there's no recursive code in the codebase or you may get burned - since stack size there will be proportional to problem size and may suddenly blow up.

Sorry that's not a more helpful answer,

Doug
0
phoffricCommented:
I looked it up and here's what I found (but never did this in Windows). Hope it helps.
Ref: https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.vcprojectengine.vclinkertool.stackcommitsize(v=vs.110).aspx
VCLinkerTool::StackCommitSize Property
Gets or sets a value indicating the total stack allocation size in physical memory.
property int StackCommitSize {
      int get ();
      void set (int value);
}
StackCommitSize exposes the functionality of the /STACK (Stack Allocations) linker option.

To change your stack size, goto Project Properties -> Linker -> System -> Stack Reserve Size (and enter your value). (I entered 4000000.)
There is also a Heap Reserve Size.
Hit Apply. Then goto Command Line, and you should see this:
/STACK:"4000000"
0
Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
I am going to look around the web and see if I can find something to tell me the stack and heap consumption. I appreciate the suggestions, I need the exact numbers so that as I add features to my code I can see how it grows.

I think I have an approach that I think will work though it is a bit clunky.
0
Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
This is the approach I was thinking of to determine stack usage
 
1) Add a MACRO that is enabled by a #define SOMEMACRO after local variables are in a method
2) This macro will create variable that is theoretically lower on the stack than the other variables I am of course assuming the pushes down in memory.

Since I have all the stack values I can calculate how far down the stack I currently am.

I cannot think of anyway to do this without instrumenting.
0
Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
I am coding up an example to determine how much stack I have used. One of the problems I ran into is that there are multiple threads running and thus I have to keep track of the stack usage on a per thread basis.
0
Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
Here is some code I wrote to determine stack depth.

While I cannot tell the absolute depth, I can tell how much the stack grows after the first time I check it.

here is what the string looks like:

thread 17056, stack depth = 50,

The code captures relative stack depth for each thread in the process
StackChecker.cpp
0
Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
I plan to give myself credit for this since I actually wrote the code to check stack depth.

I am open to suggestions ior improvement of this code.
0
phoffricCommented:
@cschene,

Could you add StackChecker.h to your solution?
Also, if you use the Code button to insert your code, it makes it simpler to review.

Thanks,
phoffric
TA
0
Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
Ok, here are both files
// StackChecker.cpp : implementation file
//

#include "stdafx.h"
#include "StackChecker.h"


// StackChecker

IMPLEMENT_DYNAMIC(StackChecker, CWnd)

    StackChecker::StackChecker()
    {
    this->id = STACK_CHECKER_ID;
    currentThreadCount = 0;
    for(int i = 0; i <  MAX_THREADS_FOR_STACK_CALCULATION; ++i)
        {
        pStartStackForThread[i] = 0;
        pLowestStackForThread[i] = 0;
        maxStackUsageForThread[i] = 0;
        }

    }

StackChecker::~StackChecker()
    {
    }


BEGIN_MESSAGE_MAP(StackChecker, CWnd)
END_MESSAGE_MAP()



// StackChecker message handlers
boolean StackChecker::ck_id() 
    {
    return true;
    }

CString StackChecker::calculateAndRecordStackUsageForThisThread(long *currentPointer) 
    {
    CString result="";
    this->ck_id();
    DWORD threadID = GetCurrentThreadId();
    result = calculateAndRecordStackUsageForThread(threadID,  currentPointer);
    return result;
    }

CString StackChecker::calculateAndRecordStackUsageForThread(DWORD threadId,long *currentPointer) 
    {
    CString result="";
    this->ck_id();

    //Find the index for this threadID and if it doe snot exist, then craete a new entry
    int thisThreadIndex = getIndexForThisThead(threadId);
    if(pStartStackForThread[thisThreadIndex] == 0) 
        {
        //this is the first time we have recorded stack information for this thraed
        pLowestStackForThread[thisThreadIndex] = pStartStackForThread[thisThreadIndex]  = currentPointer;
        }
    if(currentPointer <= pLowestStackForThread[thisThreadIndex])
        {
        pLowestStackForThread[thisThreadIndex] = currentPointer;
        }
    long stackDepth = pStartStackForThread[thisThreadIndex] - pLowestStackForThread[thisThreadIndex];
    if (stackDepth > maxStackUsageForThread[thisThreadIndex]) 
        {
        maxStackUsageForThread[thisThreadIndex] = stackDepth;
        } 
    result.Format("thread %d, stack depth = %ld", threadId, maxStackUsageForThread[thisThreadIndex]);
    return result;
    }

int StackChecker::getIndexForThisThead(DWORD id)
    {
    int result = -1;
    if (this->currentThreadCount > 0) {
        for(int i = 0; i <  currentThreadCount; ++i) 
            {
            if(this->ThreadID[i] == id) {
                result = i;
                break;
                } 
            }
        if(result == -1)
            {
            //if we get here we did not find an entry for this thread, so add one.

            this->ThreadID[currentThreadCount++] = id;
            result = currentThreadCount - 1;
            }
        } else 
        {
        //just allocate a slot to this thread
        this->ThreadID[currentThreadCount++] = id;
        result = 0;
            }
        return result;
    }

Open in new window


#pragma once


// StackChecker


#define MAX_THREADS_FOR_STACK_CALCULATION  100


class StackChecker : public CWnd
    {
    DECLARE_DYNAMIC(StackChecker)

    public:
        StackChecker();
        virtual ~StackChecker();
        CString calculateAndRecordStackUsageForThisThread(long *currentPointer);
         CString calculateAndRecordStackUsageForThread(DWORD threadId,long *currentPointer);
        CString getThisThreadStackUsage(long *currentPointer);
        CString getThisThreadStackUsage(DWORD threadId,long *currentPointer);
        int getIndexForThisThead(DWORD threadID);


    private:
        boolean ck_id();
        long id;
#define STACK_CHECKER_ID   818181
        DWORD ThreadID[MAX_THREADS_FOR_STACK_CALCULATION];
        long  *pStartStackForThread[MAX_THREADS_FOR_STACK_CALCULATION];
        long  *pLowestStackForThread[MAX_THREADS_FOR_STACK_CALCULATION];
        long  maxStackUsageForThread[MAX_THREADS_FOR_STACK_CALCULATION];
        int currentThreadCount;



    protected:
        DECLARE_MESSAGE_MAP()
    };

Open in new window

StackChecker.cpp
StackChecker.h
1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
My solution was not especially pretty code but I was looking for functionality as I need to get some idea as to how much stack I am using: It turns out only about 10,000 bytes based on the output of my stack checker
0
Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
I realized that since this code processes multiple threads it requires  a critical section. I will update the code with a critical section.
0
Christopher ScheneSystem Engineer/Software EngineerAuthor Commented:
I provided the solution myself and the code works.
0
phoffricCommented:
Thanks for sharing. :)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.