I'm currently hunting an elusive bug and have cornered it in a small portion of code where it looks like one Ice thread is smashing the stack of another Ice thread.
Until "adapter->activate();" is called (see the code below) the process is single-threaded.
After "adapter->activate();" is called a number of Ice threads are started, with one working and the rest waiting in a semaphor. This is still as I expected.
When GameClientConnPrx::uncheckedCast() is called however, an extra active Ice-thread shows up shortly, giving me a total of two active Ice-threads for a short while.
I would have expected that only one Ice-thread would be active at any given moment, with the rest waiting in a semaphor.
When the last line (::GameClient::MasterServerPrx::checkedCast(base)) is executed I again have two active Ice-threads, but this time the stack looks broken (I can reproduce it most of the time, but it does seem dependent on timing between threads).
In the stack (see stackdump below), a variable "void * pUserData", which is passed unmodified from "free()" to "_free_dbg()", has changed value from one stackframe to the next.
Also, if I read the code correctly the next stackframe after "msvcr71d.dll!_free_dbg()" should be "msvcr71d.dll!_free_dbg_lk()", not somewhere in "mswsock.dll".
This looks like something smashed the stack.
Am i misusing the Ice library by calling Ice functions (checkedCast() and such) from the main thread after starting "adapter->activate()"?
If so, then how do I interact with the Ice from my main thread?
(The main thread run a single-threaded graphics engine).
The relevant portion of code looks like this:
main() {
<< Initializing qube 3D system and loading Q-databases >>
<< calling initIceLocal()>>
[...]
}
void GameContext::initIceLocal() {
properties = Ice::Application::communicator()->getProperties();
initIceFactories();
Ice::Identity ident = Ice::stringToIdentity("GameClient_"+IceUtil::gener ateUUID());
connection = new GameClientConnImpl();
adapter = Ice::Application::communicator()->createObjectAdapter("GameClient");
adapter->add(connection, ident);
adapter->activate();
thisProxy = GameClientConnPrx::uncheckedCast(adapter->createProxy(ident));
string masterServerProxy = properties->getProperty("GameClient.MasterServer");
Ice::ObjectPrx base = Ice::Application::communicator()->stringToProxy(masterServerProxy);
masterServer = ::GameClient::MasterServerPrx::checkedCast(base);
}
***** Begin Threads at the end of initIceLocal() ******
3752 main GameContext::initIceLocal Normal 0
2336 _threadstartex std::_Tree<std::_Tmap_traits<unsigned int,IceInternal::Handle<IceInternal::EventHandler> ,std::less<unsigned int>,std::allocator<std::pair<unsigned int const ,IceInternal::Handle<IceInternal::EventHandler> > >,0> >::_Buynode Normal 0
3880 _threadstartex IceUtil::Semaphore::wait Normal 0
2148 _threadstartex IceUtil::Semaphore::wait Normal 0
232 _threadstartex IceUtil::Semaphore::wait Normal 0
2372 _threadstartex IceUtil::Semaphore::wait Normal 0
2540 Win32 Thread 7c90eb94 Above Normal 0
3744 _threadstartex _free_dbg Normal 0
***** End Threads at the end of initIceLocal() ******
***** Begin stack of thread 3744 (_free_dbg) ******
ntdll.dll!7c90eb94()
ntdll.dll!7c90e9c0()
mswsock.dll!71a53ca5()
ntdll.dll!7c90d8ef()
mswsock.dll!71a55fa7()
msvcr71d.dll!_free_dbg(void * pUserData=0x00000000, int nBlockUse=0x00000001) Line 1070 + 0x1c C
msvcr71d.dll!free(void * pUserData=0x71aa150c) Line 1025 + 0xb C
05f2e5f0()
ws2_32.dll!71ab2e67()
ice21d.dll!IceInternal::ThreadPool::run() Line 342 + 0x1c C++
ice21d.dll!IceInternal::ThreadPool::EventHandlerTh read::run() Line 813 + 0x1c C++
iceutil21d.dll!startHook(void * arg=0x053fb718) Line 203 + 0x1d C++
msvcr71d.dll!_threadstartex(void * ptd=0x053fb8a8) Line 241 + 0xd C
kernel32.dll!7c80b50b()
kernel32.dll!7c8399f3()
***** End stack of thread 3744 (_free_dbg) ******
Regards,
Richard Jørgensen
(Programmer at Runestone Game Development).

Reply With Quote