From: Charles R. <ra...@us...> - 2004-08-12 15:48:02
|
sta...@li... wrote on 08/12/2004 03:39:04 AM: > Hi all, > I'm trying to port STAF to OS/X. > I'm new to C++, (have C experience) so take it easy on > me ! > > What I've found so far is that OS/X doesn't implement > IPC (msg.h) and that means I'll have to slightly > rewrite unix/STAFEventSem.cpp to use the OS/X > MuliProcessor library (which provides a nice semaphore > implementation)... > Don't see much of a problem with doing this. Note, the code in STAFEventSem.cpp that uses things from msg.h is "dead code". This code tried to implement named event semaphores, but it doesn't actually work on most unix systems, and named event semaphores are not used in any common code or unix code. So, I'd actually suggest you try removing that header and associated code (anything dealing with STAFEventSemImplementation::kShared or !STAFEventSemImplementation::kPrivate). > I've currently got a problem after I compile staf, > with STAFProc stopping _very_ early with Abort Trap. > > I've gdb'ed this, and discovered it starts to go wrong > in STAFMutexSemInlImpl.cpp, with the method STAFRC_t > STAFMutexSem::request > When this function calls STAFMutexSemRequest, > STAFMutexSemRequest returns with kSTAFInvalidObject, > as it evaluates the mutex to be 0. > > So is it the mutex is not becoming initialised ? That is what it looks like. If the STAFMutexSem hasn't been initialized yet, then it's underlying STAFMutexSem_t will be zero, and would generate the kSTAFInvalidObject error. > I really don't understand the definition of > STAFMutexSemLock in STAFMutexSem.h which seems to be > what's being called according to gdb. > > The definition is : > > class STAFMutexSemLock > { > public: > > STAFMutexSemLock(STAFMutexSem &theMutex, > unsigned int timeout = > STAF_MUTEX_SEM_INDEFINITE_WAIT) > : fMutex(theMutex) > { fMutex.request(timeout); } > > ~STAFMutexSemLock() > { fMutex.release(); } > > private: > > STAFMutexSem &fMutex; > }; > > > Could someone explain that to me please ? It totally > threw me. Basically, the STAFMutexSemLock stores a reference (basically a pointer) to a STAFMutexSem. During the locks construction it acquires the mutex via fMutex.request(). When the STAFMutexSemLock is destructed (i.e., when it goes out of scope), the mutex is released via fMutex.release(). So, by declaring a STAFMutexSemLock object, you gain exclusive access to the associated mutex for the duration of the locks scope. Hopefully, that helped (instead of confusing things more). :) > The gdb backtrace is : (Sorry if this wraps round) > > Program received signal SIGABRT, Aborted. > 0x900429ac in kill () > (gdb) bt > #0 0x900429ac in kill () > #1 0x9009eb1c in abort () > #2 0x00abb3bc in __cxxabiv1::__terminate(void (*)()) > () at /usr/include/gcc/darwin/3.3/c++/cmath:391 > #3 0x00abb400 in std::terminate() () at > /usr/include/gcc/darwin/3.3/c++/cmath:391 > #4 0x00aa422c in __cxa_throw () at > /usr/include/gcc/darwin/3.3/c++/cmath:391 > #5 0x00b184b4 in > STAFException::checkStandardExceptions(char*, > unsigned, char const*, unsigned) (buffer=0xbffff0b0 > "STA", rc=41, errorMessage=0xaf1eb4 > "STAFMutexSemRequest", osRC=0) at > /Users/apearson/temp/src/staf/stafif/STAFException.h:167 > #6 0x00b18220 in STAFException::checkRC(unsigned, > char const*, unsigned) (rc=41, errorMessage=0xaf1eb4 > "STAFMutexSemRequest", osRC=0) at > /Users/apearson/temp/src/staf/stafif/STAFException.h:141 > #7 0x00a72048 in STAFMutexSem::request(unsigned) > (this=0xb54df0, timeout=4294967295) at > /Users/apearson/temp/src/staf/stafif/STAFMutexSemInlImpl.cpp:47 > #8 0x00b19874 in > STAFMutexSemLock::STAFMutexSemLock(STAFMutexSem&, > unsigned) (this=0xbffff6d0, theMutex=@0xb54df0, > timeout=4294967295) at > /Users/apearson/temp/src/staf/stafif/STAFMutexSem.h:139 > #9 0x00b194fc in > STAFMutexSemLock::STAFMutexSemLock(STAFMutexSem&, > unsigned) (this=0xbffff6d0, theMutex=@0xb54df0, > timeout=4294967295) at > /Users/apearson/temp/src/staf/stafif/STAFMutexSem.h:139 > #10 0x00a85dcc in > STAFStringConstructFromCurrentCodePage > (pString=0x13f0b0, from=0xc2dcc "2.6.4", len=5, > osRC=0xbffff7b0) at > /Users/apearson/temp/src/staf/stafif/STAFString.cpp:217 > #11 0x00a89694 in STAFString::STAFString(char const*, > unsigned, STAFString::CodePageType) (this=0x13f0b0, > buffer=0xc2dcc "2.6.4", length=4294967295, > cpType=kCurrent) at > /Users/apearson/temp/src/staf/stafif/STAFStringInlImpl.cpp:47 > #12 0x00a895f0 in STAFString::STAFString(char const*, > unsigned, STAFString::CodePageType) (this=0x13f0b0, > buffer=0xc2dcc "2.6.4", length=4294967295, > cpType=kCurrent) at > /Users/apearson/temp/src/staf/stafif/STAFStringInlImpl.cpp:40 > #13 0x0010eb7c in > __static_initialization_and_destruction_0(int, int) > (__initialize_p=1, __priority=65535) at > /Users/apearson/temp/src/staf/stafproc/STAFProc.cpp:141 > #14 0x0010f6f4 in _GLOBAL__I_gAPITable () at > /usr/include/gcc/darwin/3.3/c++/bits/stl_map.h:129 > #15 0x8fe17990 in > __dyld_call_module_initializers_for_objects () > #16 0x8fe17458 in __dyld_call_module_initializers () > #17 0x8fe14584 in > __dyld__dyld_make_delayed_module_initializer_calls () > #18 0x00001ed4 in _call_mod_init_funcs () at > /SourceCache/Csu/Csu-47/crt.c:299 > #19 0x00001db0 in _start (argc=1, argv=0xbffffcb4, > envp=0xbffffcbc) at /SourceCache/Csu/Csu-47/crt.c:217 > #20 0x8fe1a558 in __dyld__dyld_start () > > Can someone enlighten me a to why STAFProc aborts, and > if my assesment of what is required to port it is > correct ? This stack trace indicates that the problem is happening during static initialization of STAFProc.cpp (before it even enters main()). It appears that a static STAFString in STAFProc.cpp (of which there are several) is being constructed from a string. This causes a conversion from the current code page to UTF-8 (STAFStrings only store UTF-8 data). In order to do the codepage conversion, STAFStringConstructFromCurrentCodePage tries to get the static codepage converter, sConverterPtr. However, it sees this pointer is NULL, so it tries to lock the mutex that protects this pointer, so that it can construct the converter. However (finally), it seems as though the mutex sem itself has not been constructed yet, which leads to your failure. So, this is an ordering issue. I'm a little surprised this would only fail on OS/X, as it seems like it could happen on any unix platform. Perhaps we've always gotten lucky on ordering here. This should be able to be resolved by putting the acquisition code (and the associated mutex) in a function (in stafif/STAFString.cpp), like the following. STAFConverter *getConverterInstance() { static STAFMutexSem sConverterSem; static STAFConverter *sConverterPtr = 0; if (sConverterPtr != 0) return sConverterPtr; STAFMutexSemLock lock(sConverterSem); sConverterPtr = new STAFConverter(); return sConverterPtr; } Then, there are a couple of places where there is a loop like while (fromLen > 0) { int rc2 = sConverterPtr->convertToUTF8(&fromPtr, &fromLen, toPtr, &toLen); // Other stuff } That should change to something like STAFConverter *convPtr = getConverterInstance(); while (fromLen > 0) { int rc2 = convPtr->convertToUTF8(&fromPtr, &fromLen, toPtr, &toLen); // Other stuff } Finally, you can delete these two lines near the top of STAFString.cpp static STAFConverter *sConverterPtr = 0; static STAFMutexSem sConverterSem; > Thanks guys You're welcome. Note, SourceForge user csunsf (Chris Sun) has apparently (according to feature #991853) ported STAF to BSD (of which OS/X is a derivative), so you might want to contact him to compare notes. > PS. Wonderful product. Thanks! We like happy users. :) > PPS. I developed a plugin for a test logging system I > wrote called testmaster, which you may be interested > in mentioning in your docs. Take a look at > http://testmaster.sourceforge.net/ and goto the > documentation area Thanks for the pointer. We'll take a look at it. > > Thanks ! > > AlanP -- Charels Rankin |