Monday 7 May 2007

STLport and the problem of destructors not being called in Symbian OS

While I was away I did some additional testing on my STLport variant for Symbian OS and I noticed an annoying fact: everytime a GUI application terminates, even gracefully, an ALLOC panic is raised on the emulator indicating a possible memory leak (which is a rather common bug in programs). It turned out that STLport uses a sort of optimized allocator to manage memory allocation and deallocation for STL containers and other classes. Such allocator is a global object that pre-allocates memory on its own strategy, but it doesn't free all allocated blocks when the program ends (I think that's because the operating system is supposed to do the work). This is not a problem under normal conditions, but Symbian GUI apps usually try to detect memory leaks by marking the heap and tracking memory usage throughout the program execution, thus raising an ALLOC panic when the STL-based applications ends. Although this is benign and doesn't happen on the real device (memory leaks are only detected in debug builds), it makes the useful memory leak check completely useless, which is bad.

After a bit of investigation I discovered a configuration option in STLport that forces the optimized allocator to release all allocated memory on program termination. I tried the same test with that option turned on, but nothing changed. Apparently, the reason is much more serious than I initially thought: it seems that class destructor of global objects in Symbian applications is never called, even though it is supposed to be called (as per the C++ ISO/IEC Standard) when the program exits cleanly. In the case of STLport, this means that memory still owned by the optimized allocator is not released on exit. This is a serious malfunction of the Symbian application model in my opinion.

I asked other developers at Forum Nokia an explanation for this fact, with no luck. Some users confirmed that destructors are not being called, but neither a motivation nor a workaround emerged from the discussion. For now, I'm simply switching off the optimized allocator in STLport, falling back to the "direct" malloc/free allocator, which may be a bit less efficient but at least it doesn't leave allocated memory around.

Back to work now, more news soon.

No comments: