none
Memory allocation / memset issues RRS feed

  • Question

  • Hi,

    We are using WEC7 on an ARM platform.

    We were experiencing some issues in the USB stack and I added a class with debug code to help find the root cause. However, I am observing a strange behaviour which I am unable to understand and would appreciate any inputs on this.

    In my C++ class, I have variables declared as below:

            BOOL m_isRead;
            HANDLE m_hQueue;

            //
            // These are used to notify the readers that we have populated a new
            // message into the queue
            //
            HANDLE m_hNewMsgEvent;
            TCHAR m_eventName[STATUSQUEUE_MAXSTRINGLEN];
            BOOL m_useEventsToNotifyNewMsgs;
            
            // TODO: Remove. For debug only.
            unsigned char tempPadding[SIZE_OF_PAD_ARRAY];

    In the constructor of my class when I try to initialise the contents of tempPadding[] using memset(), I get a dataabort error.

    memset((void *) &tempPadding[0], 0xA5, SIZE_OF_PAD_ARRAY);

    If I try to print the contents of tempPadding[] BEFORE I initialises it, after printing about 60 values, I get the dataabort error.

    So it seems that when the object is being created for this class (which is by the way created via new operator, so it is on the heap), somehow memory is not being allocated correctly for tempPadding[].

    I printed the address of tempPadding[], and it seems that after the 59 values, the 60th element of the array is on address 0xB9174000.

    Questions

    1. Any pointers on why this could be happening?

    2. I know I could use some other mechanism to initialise the array (and perhaps I am not doing the right thing mixing memset in C++ code), but that is not the point. It should

    3. It is happening in the USB stack. On other instances, I have noticed some of my class members getting overwritten with data that appears to be some GUIDs something, somewhere is not handling the memory correctly. The above instance (in theory) is independent of USB related code.

    Thanks,

    Samie


    Friday, May 27, 2016 2:28 PM

All replies

  • SIZE_OF_PAD_ARRAY = 1000
    Friday, May 27, 2016 2:29 PM
  • If you try the following:

           unsigned char tempPadding[1000];

    or

           static unsigned char tempPadding[SIZE_OF_PAD_ARRAY];

    or

           static unsigned char tempPadding[1000];

    Do any of  them make a difference to the problem?



    Bruce Eitman (eMVP)
    Senior Engineer
    Bruce.Eitman AT Eurotech DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Eurotech

    Tuesday, May 31, 2016 12:44 PM
    Moderator
  • Thanks for looking into long description Bruce. Appreciated.

    Yes, making it static unsigned char makes the problem disappear - at least in my class instantiation.

    1. Also noticed that if I comment out ALL the member variables and include only another array of type TCHAR name[255], I see data abort errors.

    2. If I declare this as static TCHAR name[255], no data aborts.

    3. The above data aborts only happen when I include my class in one of the USB driver classes. The same class included in other drivers (e.g SDHC) ALWAYS works, regardless of array size, regardless of static/no static.

    So it seems a combination of this class included in the USB driver classes (specifically CRootHub created on heap i.e. new CRootHub) with NO static specifier causes data aborts.

    Seems like underneath, memory allocation is not being handled properly but then I dont understand why do I see it only for the USB driver.

    Wednesday, June 1, 2016 11:17 PM
  • Same

    Your function is attempting to out massive amounts of data on the stack - which us never a good programming practice.  So depending on how you expect the function to be called, you should allocate in a different way.

    Either using static or declaring global will allocate exactly one instance of the data.

    If you need multiple instances, use the heap by allocating at runtime using malloc or new.

    Why "only when in the USB driver"?  The answer is that your sample size is too small.  It will fail in other large code that uses a lot of stack space.



    Bruce Eitman (eMVP)
    Senior Engineer
    Bruce.Eitman AT Eurotech DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Eurotech

    Thursday, June 2, 2016 11:12 AM
    Moderator
  • Thanks Bruce.

    The class of which this array was a member created via new operator, so it must be on heap and was not created on stack.

    Nevertheless, I have found that even if I reduce the size of the array to just 8 bytes, I still get 'data abort' exception during instantiation of the class. So it seems that it is not the huge size but its allocation somehow causing an issue.

    I followed your article to find the source of data abort (great article by the way!). It happens during the constructor of the class (which had no code in it), so it must have been happening during the object creation.

    Strange thing is that the same class created in an another driver consistently works.

    Thursday, June 2, 2016 1:54 PM
  • One other thing that I am trying to understand is this: the entire class (or specifically object) of which my class is just a member variable is created via new. So all of it should go on heap.

    However, when I print the addresses, addresses of member variables are 0xB9128F9x but the addresses of those variables that were 'static' had address 0xeeeF62E0.

    Since ALL of above are created on heap, I am trying to understand why the difference in the regions (member variable allocation in a different region vs static variables in another region)? The class was created via 'new' so everything is going on heap so why such a big difference?

    Perhaps those with static are in different region because their address is determined at compile time, whereas those with new are dynamically allocated .... ?

    Thursday, June 2, 2016 5:43 PM
  • Samie

    You are asking some fairly basic programming and C/C++ questions here.  Maybe you should do some research to determine what is going on.

    To get you started:

    1.  Heap is space that code can request some storage from using new and malloc.

    2. Stack is space used by functions to store local function variables (like your arrays) and information to return to the calling function/location.  Threads have stacks, classes do not.

    3. The use of the keyword "static" can affect two things; scope and storage.  Storage as in making a local function variable a global variable, but with limited scope.



    Bruce Eitman (eMVP)
    Senior Engineer
    Bruce.Eitman AT Eurotech DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Eurotech

    Friday, June 3, 2016 3:04 PM
    Moderator
  • Hi Bruce,

    May be I didn't word my question clearly. I wasn't so much looking for an explanation for difference between stack/heap and their usage. Stack is not even an issue here. Nor I was looking for an explanation for scope of variables (though thanks for providing that information).

    It was more trying to understand differences in areas allocated via 'new' vs static, especially in the context of WEC7 architecture. I have come to realise that static vars will be allocated memory in BSS/DATA region so it does answer some of my questions.

    Anyway, this is enough for my debug at the moment. Might post with more information if/when I have it.

    Monday, June 6, 2016 12:45 PM