In the end, it appears that when DLL’s with symbols get loaded during unit initialization sections, the Delphi IDE (in this case 2007) loses the Symbol Tables either for the EXE or for the DLL (or both).

In order to work around this:

We had to know which DLLs were loaded and when

We rewrote all the DLLs to be ‘demand/delay loaded‘ (i.e. not statically linked, see code sample below)

We rewrote all the stuff that referenced the DLLs to initialize on demand as well

Here are some tips for setting breakpoints to debug the startup sequence, including some links to relevant documentation, samples or articles:

Unit System; procedure InitUnits; line “TProc(P)();”
(this line gets called often: for each unit that is being initialized, either because the unit has an initialization section, or it has initialized consts; see an example call stack) .

Unit SysUtils; procedure SafeLoadLibrary;
(we call this for every DLL that gets loaded; this method saves and restores the FPU control word, especially handy for 3rd party DLLs that think they own the FPU).

unit System; procedure _InitLib; line “MOV EDX,offset Module”
(this gets called in a DLL when Windows is loading it with LoadLibrary)

unit SysInit; procedure InitProcessTLS;
(inside a DLL this reserves the Thread Local Storage to be used by this DLL; it usually is the first thing called in a DLL)

unit System; procedure ExitDll; line “RET 12” (assembler)
(this gets called in a DLL when Windows is almost finished processing the LoadLibrary for it)

DLL kernel32.LoadLibraryA and DLL kernel32.LoadLibraryW, CPU code “cmp dword ptr [ebp+$08],$00”, then in the data portion of the CPU viewer, go to the address “ebp+$08” , then press Ctrl-D to follow “long data”; now you see the module that is going to be loaded
(this gets called by Windows when loading DLLs)

It loses symbols for the System unit (among other things) when you load a package, because the package has to load RTL???.bpl instead of the RTL you’ve got linked in, if you had one, and Embarcadero doesn’t ship a debug-enabled version of the runtime packages. We have debug DCUs, but not debug DCPs.

I think you might be right, my first guess was also that having more than one RTL in memory at the same time would confuse the IDE.
Chris Hesik hinted that debug DCPs might become available in the comments thread of this post.

But on the other hand, so far when loading those DLLs outside the initialization section of the EXEs units, everything goes dandy.
So I’m not completely convinced :-)