Open C Tips and Tricks |
Since Symbian OS has different mechanisms for handling or trapping errors and exceptions, standard libraries written on top of Symbian as part of Open C, may throw some panics or crash with Symbian-specific errors. This section lists out the possibilities of such a scenario.
Even though such errors can happen, these error cases can be eliminated if the user is aware of them and knows the solution.
Open C libc will panic during the startup of the application (before callingmain( ) of the application) if any of the following happens:
In either of the above cases, the application will panic before starting main( ) of the application.
In addition to the above Panics, applications linking with Open C STDLIBS may also panic or crash because of a bug introduced by the programmer.
One such common example can be an application panicking or crashing with the User-42 panic code. This may happen with those APIs of libc that use malloc, calloc, free, or realloc. See the code below:
#define ALLOC_DATA 500 int main() { char* p = (char*) malloc(1); /* Suppose to allocate ALLOC_DATA, but 1 byte is allocated, still doing memset for ALLOC_DATA length */ memset(p, 0, ALLOC_DATA); /* This will crash now, as heap is corrupted by previous memset */ char* q = (char*) malloc(ALLOC_DATA); free(p); free(q); }
This code has a bug that will cause the application to panic with User-42. This panic will be raised when the programmer tries to do allocation or reallocation or freeing up of memory from RHeap and if the address passed is not a valid cell (Bad Heap Cell Address).
In case of hybrid applications, the users may end up with several problems if they are not aware of the limitations that are mentioned in Introduction to Open C.
Some APIs expect a cleanup stack to be created and that a top-level TRAP is present. Using such APIs of libc like select, any pipe-related APIs (pipe, read, write on fd of a pipe), some socket-specific APIs, locale-specific APIs, iconv_open, mmap API, and ipc-related APIs may cause panics like E32USER-CBase:66 or E32USER-CBase:69 depending on whether the application has created a cleanup stack or whether a top-level TRAP/TRAPD exists. One such example can be:
void PipeTestL() { int fds[2]; int ret = pipe(fds); printf("pipe returned with %d", ret); close(fds[0]); close(fds[1]); } TInt E32Main() { __UHEAP_MARK; TInt retVal = KErrNone; TRAP(retVal, PipeTestL()); HelloWorldL(); __ASSERT_ALWAYS(!retVal, User::Panic(_L("Pipe Test PANIC"), retVal)); __UHEAP_MARKEND; return retVal; }
The above sample will panic with E32USER-CBase:69 because a cleanup stack is not created. The solution is to create a cleanup stack in E32Main() as in the example below:
TInt E32Main() { __UHEAP_MARK; CTrapCleanup* cleanup = CTrapCleanup::New(); TInt retVal = KErrNone; if (cleanup) { TRAP(retVal, PipeTestL()); HelloWorldL(); __ASSERT_ALWAYS(!retVal, User::Panic(_L("Pipe Test PANIC"), retVal)); Destroy cleanup stack delete cleanup; } __UHEAP_MARKEND; return retVal; }
Similarly, for threads created using direct Symbian APIs, the user has to take care of these limitations (cleanup stack and TRAP or TRAPD). The user does not have to create a cleanup stack or trap if the application has main( ) as the entry point and all the threads are created using the pthread_create API. This is because pthread_create will take care of creating the cleanup stack and trap for that thread.
In addition to the above, some common coding mistakes such as operating on uninitialized fds or file pointers will cause the application to crash with KERN-EXEC 3. This panic will be raised when an unhandled exception occurs, like de-referencing NULL or executing an invalid instruction. One such example can be:
void FileTest() { FILE* fp = NULL; int ret = fprintf(fp, "write me"); fclose(fp); }
This sample case will panic with KERN-EXEC 3 since fp is not pointing to a valid file.
©Nokia 2007 |