set WINCECOD=1, build –c, and then open the COD file from obj\%_TGTCPU%\%WINCEDEBUG%. It’ll be named after the C or CPP file – in this case devpnp.cod. The function name will appear several times in the COD file, but in only one case will the function name be followed by the word “PROC,” and this is the beginning of the assembly code for that function. Here’s a sample that’s munged a little from reality.
As you can see, the source code and line numbers are included in the COD file next to the assembly code that implements the source. Each assembly instruction is labeled with an address. So the COD file provides the mapping from function offset to source line. Sometimes the assembly for the function is labeled starting with 0, and sometimes not. (I believe it may depend on which compiler is being used – meaning it varies by CPU type.) If not, you have to take the function start label into account. So in this example the function starts at label 0x001E8.
Platform Builder: Find the Source of a Data Abort; an Example http://geekswithblogs.net/BruceEitman/archive/2008/06/02/platform-builder-find-the-source-of-a-data-abort-an.aspxPreviously I posted instructions for finding the source of a data abort, see Windows CE: Finding the cause of a Data Abort. This will walk through those steps to find the source in a real application for. This is specific to Windows CE and later.
From this, I can see that it is in lan91c111.dll. Lan91c111.dll is my Ethernet driver. I was just making changes to it, so I could go back and review my changes for hints. But let's find it from the Data Abort output.
We can also see that the Return Address (RA) is at 0x000038a8
Subtract 0x1000 to find the Module Offset(MO) of 0x000028a8
We can now look up the Module Offset in lan91c111.map. Here is a small section of lan91c111.map:
Address Publics by Value Rva+Base Lib:Object
0001:00002780 READ_ETH_USHORT_32BIT_MODE 10003780 f LAN91C111_Init.obj
0001:00002798 WRITE_ETH_USHORT_32BIT_MODE 10003798 f LAN91C111_Init.obj
0001:000027cc WRITE_ETH_CUSTOMIZE_USHORT 100037cc f LAN91C111_Init.obj
0001:00002820 LAN91C_Write16 10003820 f LAN91C111_Init.obj
0001:00002884 LAN91C111_MiniportInitialize 10003884 f LAN91C111_Init.obj
0001:00002fc4 LAN91C111_MiniportISR 10003fc4 f LAN91C111_Intr.obj
Looking at the addresses we find that the MO is between 00002884 LAN91C111_MiniportInitialize and 00002fc4 LAN91C111_MiniportISR. That tells us that the Data Abort occurred in LAN91C111_MiniportInitialize. To calculate the Instruction Offset(IO) subtract the Function Offset(FO) from the Module Offset: 0x00002858 - 0x00002884 = 0x28.
The file that contains LAN91C111_MiniportInitialize is Lan91C111.c, which we know because of the name of the object file that the function is in. But, what we need is the COD file, which contains the C code as comments mixed with the assembly code that was created when the file was compiled. The COD files are in the same folder that the OBJ files are in. If you don't have the COD files, set WINCECOD=1 and rebuild.
Looking in the COD file, find the function; in this case LAN91C111_MiniportInitialize. This is what mine looks like:
The numbers on the left of the assembly code are the Function Offsets, and we can see that at offset 0x28 we have:
00028 e5931000 ldr r1, [r3]
Which is dereferencing an indirect address which we can see is the *ptr in the C code above it:
; 156 : RETAILMSG( 1, (TEXT("*ptr %X\n"), *ptr ));
Now the hard part, why is dereferencing the pointer a problem? In this case, it is because ptr is NULL, but you may need to get out a debugger to find the cause. But at least we now know where the problem is.
In some cases, you may need to start with the Program Counter (PC) insteaad of the Return Address (RA) to find the source of the problem.