Jump to content
  • Advertisement
Sign in to follow this  
shaitan

STL Vector & Multithreading

This topic is 4611 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I seem to be having some problems with code relating to std::vector and multithreading.... I create a thread, the threads process calls a function which fills a std::vector with data. Just before the thread returns I test the data in the vector and it is good. After the thread returns I test the data in the threads calling process, and it appears some of the data in the vector is corrupted, not all of the data, only some. This only happens on Debug builds and it only happens the first time the build is launched. If launched a second time the data in the vector is fine. If rebuilt, the first time it is launched it will have corrupt data again... This problem doesn't arise in release builds.... Here is some pseudo-code
Quote:

int Main()
{
    CreateLoaderThread( LoaderThreadProcess );    // _beginthreadex

    WaitForLoaderThreadToFinishExecution();       // Wait for thread to complete

    TestDataInSTLVector();                        // Some data is corrupt
}


__stdcall LoaderThreadProcess()
{
    GetFirstData();

    while( DataIsGood() && DataExists() )
    {
        LoadSTLVectorWithData();
        GetNextData();
    }

    TestDataInSTLVector();   // Data is fine
    ExitThread();
    return;
}


int LoadSTLVectorWithData()
{
    DataStruct dataStruct;

    InitializeDataStruct(&dataStruct);   // Initialize all struct members

    dataStruct->data = 0;             // Set struct data here

    vecVector.push_back(dataStruct);     // Push struct onto vector
}

This isn't how my code really is, but it's a fair enough approximation for this question I hope. The fact that the problem only happens on the first launch of a fresh Debug build led me to beleive that it was the result of a variable not being properly initialized. Then I started testing the data in the vector in the thread procedure just after the vector is finished being filled, and the data is fine at this point within the thread procedure. The data in the vector isn't corrupted until after the thread procedure has exited. I'm wondering if anyone has any suggestions... I'm using Visual Studio 2003. Thanks... [Edited by - shaitan on February 28, 2006 11:10:32 AM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by bakery2k1
Try removing the call to ExitThread, and simply returning from the thread function.

I will give that a shot....

Quote:
Original post by NotAYakk
Contents of LoadSTLVectorWithData() please. =)

I've edited my original post to show pseudo-code for the
LoadSTLVectorWithData() sequence..

Share this post


Link to post
Share on other sites
Does the vector contain pointers, or full-copies of the struct in question?

Do the structs contain any pointers?

What does the "corrupt" data look like? (In hex ideally -- 0xFEEEFEEE? 0xBAADF00D? 0xFEFEFEFE? 0x00000000?)

The bit patterns of corrupt data can tell you alot. Some compilers in debug mode blit cleared/deallocated/uninitialized/beyond top of stack memory with characteristic patterns.

One possibility is you are sticking pointers to data on your thread's stack into the vector. When the thread exits, the thread's stack in debug is likely to be cleared/written over with a bit pattern, but in release it will be left alone.

Share this post


Link to post
Share on other sites
Quote:
Original post by bakery2k1
Try removing the call to ExitThread, and simply returning from the thread function.



I've just finished trying that and it didn't help. Thanks for the suggestion anyway.


I'll give a little more information on what I have done.

The entire code in question resides within one DLL....

Basically what I am doing is calling a thread to load graphic resources into memory.
I'm using a thread so the owning process can perform its rendering duties without having
to wait for the graphic resources to be loaded.

Originally I was using the CreateThread() API call to create my thread... but after this problem
started arising and I did some investigating I switched to the _beginthreadex() method, this appears
to be the better method of thread creation but it had no visible impact on the problem.

I also realized while investigating the problem, that I had the compiler set to use the single-threaded
runtime library, I changed the switch to "Multi-threaded Debug DLL", this had no visible impact on the
problem either. (But seems to be the correct setting for a Debug Build of a DLL which creates a thread(s))


I've tried various combinations with/without _endthreadex() and/or ExitThread() at the end the threads
process function, this didn't help, thanks anyway bakery2k1, it was a good suggestion and something that
I had not tried.

This is an annoying problem, mainly because it is impossible for me to pin down exactly when it started
and what I may have changed in the code to make it happen. I was in the process of adding (and debugging)
sections of code functionality, it wasn't till I had finished adding and debugging much code that I even
realized that this was happening, (It took me a little bit to figure out that this problem was happening
only on the first run of a freshly compiled debug build).




This is an excerpt of relevant sections of my debug log:

Quote:

Start DataLoading Thread

Load Data to vector using loop

winGreenSmoke1.bmp rsGraphic.m_pMemPosition: BMøž

winGreenSmoke2.bmp rsGraphic.m_pMemPosition: BM
winGreenSmoke3.bmp rsGraphic.m_pMemPosition: BMøž

winGreenSmoke4.bmp rsGraphic.m_pMemPosition: BMøž

winGreenSmoke5.bmp rsGraphic.m_pMemPosition: BMøž

winGreenSmoke6.bmp rsGraphic.m_pMemPosition: BM8)

After all data is finished loading, test it for validity

MEMPOS: BMøž

MEMPOS: BM
MEMPOS: BMøž

MEMPOS: BMøž

MEMPOS: BMøž

MEMPOS: BM8)

Exit From DataLoading Thread


Now test data again in the owning process that created the DataLoading Thread

MEMPOS: Memory: BMøž
-- Most data is fine
MEMPOS: Memory: BM
MEMPOS: Memory: BMøž

MEMPOS: Memory: Ý%MÁé?xaqÉ8jG'9ÒŽ“..... etc.... -- Some data seems corrupt
MEMPOS: Memory: +è)Ñ‘]q¥@Õv‚bž’¸&èF..... etc....
MEMPOS: Memory: Ç÷Inˆ¬©t‚"qÓ“@°NÉÖŠšK..... etc....


The data that appears to be corrupted seems to always be at or near the vector.end() ussually the last
three entries in the vector are corrupt.

Share this post


Link to post
Share on other sites
Quote:
Original post by NotAYakk
Does the vector contain pointers, or full-copies of the struct in question?

Do the structs contain any pointers?


vector contains full-copies

structs contain pointers
Quote:


struct DataStruct
{
int iWidth;
int iHeight;
char pszName[MAX_CHAR];
unsigned char* pMemPosition;
unsigned int uiMemDataSize;
LPDIRECT3DSURFACE9 pSurface;
}



The only struct member that seems to be affected is the pMemPosition.
All other members seem to be unaffected.

Quote:

What does the "corrupt" data look like? (In hex ideally -- 0xFEEEFEEE? 0xBAADF00D? 0xFEFEFEFE? 0x00000000?)

The bit patterns of corrupt data can tell you alot. Some compilers in debug mode blit cleared/deallocated/uninitialized/beyond top of stack memory with characteristic patterns.

One possibility is you are sticking pointers to data on your thread's stack into the vector. When the thread exits, the thread's stack in debug is likely to be cleared/written over with a bit pattern, but in release it will be left alone.


Sample Data that appears corrupt
Quote:

Memory: Ý%MÁé?xaqÉ8jG'9ÒŽ“gI½ HOé°X9ЫLµÕ—;
Memory: +è)Ñ‘]q¥@Õv‚bž’¸&èFH8ã®°‰Óu`ry@
Memory: Ç÷Inˆ¬©t‚"qÓ“@°NÉÖŠšK¦x48­žf¤C«
S@0‡HÊ

Share this post


Link to post
Share on other sites
Lets look at pMemPosition; then.

Is pMemPosition itself being corrupted, or the data that pMemPosition points to?

(you may have to print-debug this, and see if pMemPosition is changing on you, or if it is the data pMemPosition is pointing to that is changing)

Share this post


Link to post
Share on other sites
Quote:
Original post by NotAYakk
Lets look at pMemPosition; then.

Is pMemPosition itself being corrupted, or the data that pMemPosition points to?

(you may have to print-debug this, and see if pMemPosition is changing on you, or if it is the data pMemPosition is pointing to that is changing)


It appears that it is the data that is being corrupted.
I've tested the address value of the pointer and it seems to remain
correct in the thread and after the thread.

Thank you very much NotAYakk, for taking the time to consider my problem...
It is much appreciated...

Share this post


Link to post
Share on other sites

I should probably mention that the Data that pMemoryPos points to
is a subsection of a larger chunk of memory that was allocated with
malloc()

Example:
Quote:

Allocated Memory Chunk
[[DATA_SET_01][DATA_SET_02][DATA_SET_03][etc...]]


What I wonder about is the fact that the problem happens only on the
first execution of a Debug Build, and not on subsequent executions of
the same build.

I've had that type of problem before and it has always been the result
of a variable, ( usually a char[] ), not being properly initialized.
I suspect that when this type of problem happens, on the first execution
the improperly initialized variable causes a lock-up/crash, but at the
same time something happens within Visual Studio(?) that causes the
variable to act as if it is properly initialized on subsequent executions.
When I've had problems similar to this in the past, the release build
would consistently lock/crash.

This does not appear to be the case this time though.



Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!