Finding Initialized or Uninitialised static data in a DLL
14 sept. 2004 - 14:36
Keywords :

Introduction

The Symbian operating system does not support the use of writable static data in DLL's. This can be a major problem if your application uses global variables.

There are a number of quick tricks that can be used in the Symbian tool chain to fix this problem quickly and easily. So whilst your application may build and run without problems on the emulator, it will fail to build using the ARM chipsets. Typically the error you will see will be

“ERROR: Dll ‘(null)'” has initialised data”

Symbian do a good job of explaining why the error occurs in FAQ-0329, however they unfortunately left out how to find out which variable(s) is/are causing this error.

Finding uninitialized data

As with most things identifying you have a problem with non-const data is easy, you will find that your DLL does not build. Fixing it is harder however.

Below are the steps that need to be taken to identify and then isolate the offending variables in the source code.

Configuring your Project

A little used feature of the mmp file format is the OPTION command. In this case we use it to tell the Tool Chain that we want to add to the build flags for GCC compiler.

This option avoids either patching the perl script (ugly) or patching the generated make file from abld which are overwritten each time the build process is triggered.

The MMP file will need to be changed and the line below added to the top of the mmp file, after the UID declaration.

OPTION GCC  -save-temps.

This line will add thus the “-save-temps” configuration to the GCC make file when it is built using the bldmake/makmake process. This command informs GCC to save the intermediate files that it generated so that it can be used later to see what went wrong. In our case it holds lots of clues about where we can find the static data that should not be there.

The project can now be regenerated using the BLDMAKE or MAKMAKE programs in the Symbian tool chain. Once these have been run and the make file created, it can be built.

During the build process a warning may be displayed “Warning: -pipe ignored since -save-temps specified” This message can safely be ignored as it is just indicating that we have overridden a GCC option.

Identifying the Writeable Data

By adding the “-save-temps” command to the compiler command line, this will generate a “.i” and a “.s” file in the directory where abld was created, this is normally the same directory as your bld.inf file.

If you are a command line wiz you can use grep command to find out which files have a “.data” and/or a “.bss” section in them. Alternatively just use the find in files functionality that is in most IDE's to search the project directory (i.e. the bld.inf directory) for all files the have an extension of “.s” and contain the phrase “.bss” or “.data” “.bss” is the uninitinalized data section “.data” is the initialized data section. It is now a simple case of finding all the files with a .bss or a .data section in them, locating them in the “.s” file and then finding out the variable associated with the section.

Appropriate action can then be taken to fix the problem with the writable data.

A Short Example

This bit of code itself is very simple:

static unsigned char UnInitializeData[4];
static char* NonConstData[1] = NULL;

We have two declarations for the variables, either one of which will cause build problems.

First you will need to comment out all the lines. Next, uncomment NoConstData and see that it generates a DLL has initialized data error in linking.

Next, comment out the NonConstData line and uncomment the UnInitializedData line and see that it generates a DLL has Uninitialized data error. Make sure both the lines are uncommented and do a build.

You will get errors. Open the generated “StaticData.s” file and search for the “.bss” string which is the uninitialised data section. You will see the intermediate code as below:

@ Generated by gcc 2.9-psion-98r2(Symbian build 542) for ARM/pe

   .file "Staticdata.cpp"

.gcc2_compiled.:

   .section .rdata

   .align 0

.LC0:

   .ascii "test\000"

.data

   .align 0

NonConstData:

   .word .LC0

.text

   .align 0

   .global E32Dll__F10TDllReason

E32Dll__F10TDllReason:

   @ args = 0, pretend = 0, frame = 0

   @ frame_needed = 0, current_function_anonymous_args = 0

   mov r0, #0

   mov pc,

   lr

.bss

   UnInitializeData: .space 4

The .data and .bss data sections are the variables that have writeable data, in this case it is both initialized and uninitialized data. Fixing both these so that they are const and initialized will make the DLL build correctly

Acknowlegements

I would also like to extend my thanks to Simon Woodside who showed the -save-temps trick in GCC on his blog.

Fichier attachéTaille
StaticData.zip964 octets
Tutorial posted septembre 14th, 2004 by paul

Soumis par Anonymous le sam, 2004-11-13 15:20.

There is an error when i try to compile. Unrecognize Keyword "OPTION".

How do i resolve this?


Soumis par Anonymous le sam, 2004-11-13 17:18.

Did you put the option key word in the mmp, and then regenerate the build files using bldmake/makmake?

What version of symbian are you using?


Soumis par Karsten Meier (non vérifié) le jeu, 2004-11-25 10:56.

I have the problem, but only in Series60 v1.2, In Series60 v2.0 it works.

Soumis par Lin Ma (non vérifié) le ven, 2004-12-24 10:14.

Hi, the problem is that your sdk does not support the keyword "OPTION". As I know, the 6.0 version doesn't, you can't find the keyword in it's sdk ( » Symbian OS v6.1 Edition for C++ » Tools And Utilities » Build Tools Reference » mmp file syntax).

Soumis par amine (non vérifié) le ven, 2006-04-21 12:09.

how can i add this option under carbide thanks

Soumis par Anonymous le lun, 2007-02-05 20:59.

To use the .BAT file in Carbide-c++:
-  duplicate the folder named "UIQ 2.1 Phone (ARMI) Release" (or similar) of your Carbide project to a name WITHOUT SPACES (e.g. "ARMISOURCES")
-  then copy NM.EXE from C:\symbian\UIQ_21\epoc32\gcc\rm-epoc-pe\bin to ARMISOURCES\SRC folder
-  save the .BAT file in ARMISOURCES\SRC folder
-  open a DOS box
-  enter ARMYSOURCES\SRC folder
-  run vsvars32.bat batch file from Visual C++ compiler installation (mine is in ....\Common7\Tools\vsvars32.bat )
-  finally, run the .BAT file.

Soumis par Drew Haninger (non vérifié) le dim, 2004-12-12 23:34.

Does this method work for the UiQ builds ?

I cannot find any .s or .i file after the builds.

thanks Drew


Soumis par Anonymous le lun, 2004-12-13 14:15.

I did all the testing on the UIQ toolchain as this is my primary developer platform.

Did you run makmake or bldmake and then a full rebuild using abld?

Did you search you harddrive for any of those file types?


Soumis par Asmo Soinio (non vérifié) le mar, 2005-07-26 13:30.

Hi, thanks for the article!

I used this method with Metrowerks CodeWarrior: In Targets, selected settings for ARMI UDEB and added "-save-temps" to Code Generation / Symbian Compiler / Arguments.

The .s-files were generated to epoc32\gcc\bin\


Soumis par Anatoly kardash (non vérifié) le jeu, 2005-08-11 17:51.

There is a simpler method to find the problematic variables (using "nm" utility provided with GCC). I created a simple batch file to find the modifiable statics:

rem ------ start of find_statics.bat ------

@echo off

for /R %%f in (*.o) do ( echo %%f & nm %%f > tmp.txt & find /I " d " < tmp.txt & find /I " b " < tmp.txt & find /I " g " < tmp.txt )

del /f tmp.txt 2> NULL:

rem ------ end of find_statics.bat ------

(Please note that it uses MSWin2K/XP CMD.EXE with Command Extensions enabled. And, of course, it is possible to write much more elegant script using UNIXish utilities :-).

Well, just copy the lines above to, say, find_statics.bat, go to BUILD directory of you application/DLL, and run the batch, e.g.

c:\> cd c:\Symbian\7.0s\Series60_v21\Epoc32\BUILD\MY_APP\GROUP

c:\Symbian\7.0s\Series60_v21\Epoc32\BUILD\MY_APP\GROUP> find_statics.bat

The result will be something like:

c:\Symbian\7.0s\Series60_v21\Epoc32\BUILD\MY_APP\GROUP\MY_APP\THUMB\UREL\GOOD1.o

c:\Symbian\7.0s\Series60_v21\Epoc32\BUILD\MY_APP\GROUP\MY_APP\THUMB\UREL\BAD.o

00000008 d PROBLEMATIC_VARIABLE1

00000004 d PROBLEM_VAR2

c:\Symbian\7.0s\Series60_v21\Epoc32\BUILD\MY_APP\GROUP\MY_APP\THUMB\UREL\GOOD2.o

Good luck!


Soumis par Anonymous le lun, 2006-05-08 16:12.

Yes, this batch file is much better than the method proposed by the orignal post. I tried both and this one helped me to find my problem. And it is much faster.

Thanks Ray


Soumis par Felix (non vérifié) le ven, 2006-05-26 17:33.

THANK you, this tool helped me fix my problem within seconds, and it didn't require me to fully understand the why. That's really helpful.

Soumis par euroq (non vérifié) le ven, 2006-10-13 21:37.

Interestingly enough, the find_statics.bat will actually find more instances of initialized data than the method mentioned in the article (looking for the bss section), as there are some cases where initialized data doesn't create a bss section.


copyright 2003-2009 NewLC SARL