Map File Breakpoints

While debugging, I am often faced with trying to set breakpoints in module code that I do not control. Said modules rarely have current symbols and access to source files either not possible or practical. I usually face these issues armed only with a call stack and a [possibly ancient] map file in which to determine the root cause of the error. I like to convince myself that single-stepping through code would be too easy and debugging ASM to find the problem makes things more interesting. Sometimes it works.

To get started, you need to guess where it is you would like to go – if you have a call stack, this is the function name at the top of the list. First try to set this breakpoint in the breakpoint window using the following format:

{,,ModuleName.dll} FunctionName

Please note that the FunctionName is case sensitive, but the ModuleName is not. If you run through your repro and the debugger did not break, we need to dig a little deeper and make sure we are actually using the correct module name. First, load the Platform Builder “Modules” window (View->Debug->Modules) and look for the module name in the list – remember that during makeimg, modules will often be renamed as they are added to the ROM. If you are certain of the module name, lets find the “base” of this module by breaking at DllMain (or WinMain for EXE’s).

{,,ModuleName.DLL} DllMain


{,,ModuleName.EXE} WinMain

DllMain is often a convenient breakpoint since it is called often, not just on load/unload. Once we are stopped at DllMain, the ease of finding other breakpoints within this module will depend on how old your map file is. If the module has undergone significant changes, the below may not work, but in my experience map files are usually “close enough” to get what you need. Open the map file and find the function you are trying to break at:


 0001:0002fab4       ?ParseGetCallerIdSettings@@YAJPBDAAPAXAAI@Z 10030ab4 f   supsvc.obj
 0001:0002fdd4       ?ParseGetHideIdSettings@@YAJPBDAAPAXAAI@Z 10030dd4 f   supsvc.obj
 0001:00030138       ?ParseGetDialedIdSettings@@YAJPBDAAPAXAAI@Z 10031138 f   supsvc.obj
 0001:000303f8       ?ParseGetClosedGroupSettings@@YAJPBDAAPAXAAI@Z 100313f8 f   supsvc.obj
 0001:00030810       ?ParseGetCallForwardingSettings@@YAJPBDAAPAXAAI@Z 10031820 << HERE HERE HERE
 0001:00031338       ?ParseGetCallWaitingSettings@@YAJPBDAAPAXAAI@Z 10032338 f   supsvc.obj
 0001:00031920       ?BSCompareChars@@YAHPBX0@Z 10032920 f   util.obj
 0001:00033018       ?ParseGetAudioGain@@YAJPBDAAPAXAAI@Z 10034018 f   voice.obj  



The function I want to stop at is the RIL component ParseGetCallForwardingSettings() and is located at: 10031820. This number is not an address, but rather an offset that we can use to calculate how much code lies between this function and DllMain. Looking at the same map file, locate DllMain:



 0001:00029914       ?StartReadyStateQuery@CRilHandle@@QAAXXZ 1002a914 f   rilhand.obj
 0001:00029960       ?Register@CRilEventLog@@QAAJXZ 1002a960 f i rilmain.obj
 0001:000299c0       DllMain                    1002a9c0 f   rilmain.obj
 0001:00029a10       ?RIL_Deinit@@YAHK@Z        1002aa10 f   rilmain.obj
 0001:00029aec       ?RIL_Read@@YAKKPAXK@Z      1002aaec f   rilmain.obj
 0001:00029af4       ?RIL_Write@@YAKKPBXK@Z     1002aaf4 f   rilmain.obj

Using calculator, find the amount of code that exists between these two functions. In this case, my function is later in the map file than DllMain so I Subtract:

10031820 - 1002a9c0 = 0x6E60

To get the code offset between these two functions. Going back to the debugger, locate the instruction address of DllMain and drag this into a watch window.


0102A9B8    bx          lr
0102A9BC    andhi       r4, r0, r5
0102A9C0    stmdb       sp!, {r4, lr}    <<< HERE
0102A9C4    cmp         r1, #1
0102A9C8    bne         |$M46300+18h (0102a9dc)|
0102A9CC    ldr         r0, [pc, #0x38]
0102A9D0    bl          |CRilEventLog::Register (0102a960)|




Next, use the watch window to help your function by adding your offset value to the instruction address of DllMain. Note: if your function was less than DllMain, you would actually subtract:




Click and drag this resulting value back to the ASM window to find code close to your function. Looking at the ASM, you will see that we are very close to the top of a function and should set a breakpoint here.


Hint: Look for stmdb instructions and SP register manipulation to show you the beginning and end of functions.



010317EC    ldmia       sp!, {r4 - r8, lr}
010317F0    bx          lr
010317F4    andhi       r4, r0, r5
010317F8    ???
010317FC    smlabbeq    r0, r12, r3, r2
01031800    ldreqd      r8, [r0, -r12]
01031804    smlatteq    r0, r12, r2, r8
01031808    andhi       r0, r7, r7, asr r0
0103180C    ???
01031810    mov         r12, sp  << Func begins here
01031814    stmdb       sp!, {r0 - r3}
01031818    stmdb       sp!, {r4 - r12, lr}
0103181C    sub         sp, sp, #0x86, 30
01031820    mov         r7, r2   << HERE
01031824    mov         r8, r1
01031828    str         r0, [sp, #0x240]
0103182C    ldr         r3, [pc, #0x3C4]
01031830    ldr         r3, [r3]
01031834    str         r3, [sp, #0x214]
01031838    mov         r1, #0
0103183C    str         r1, [r8]
01031840    str         r1, [r7] 






The specific case above puts us very close to the top of a function – but is it the function we are looking for? It is hard to say without setting breakpoints and continuing to see if we stop. Don’t be shy about scrolling through the ASM looking for other functions nearby and setting multiply breakpoints (they are free!) on those as well. Function prologs have a certain “look” about them and your eye will train to identify them quickly.

The above steps will not work under all conditions and significant module changes can render older map files useless. But, as the device matures and code churn is reduced – I have found this method very useful. Good Luck!

Comments (4)

  1. Posted by: Sue Loh I’ve been working with one of our customers the last couple of days, and found that

  2. fei says:

    sometimes I got Watson dump file, when I view with UIDumpViewer, the symbol of coredll never shows, it only show some address, but others dll’s symbol show properly.

    what should I do to fix it. In this case, does map file address still apply?

    I am using WM6.

  3. elexx-bd says:

    <a href= >jimm .6 2 jar</a> <a href= >������� ���������� ��� ����� ����������</a> <a href= >������� ���������</a> <a href= >www ������������� km ru</a> <a href= >������� ������ �����</a>

  4. Alexander says:

    BTW, could someone explain what the ‘i’ character in a mapfile indicates?

Skip to main content