FAQ

What can EACallstack do?

EACallstack has the following functionality:

What can EACallstack not do?

It is not a generic debugger engine. While it can do address-to-symbol lookups, it can't tell you anything more than that, such as give you a list of all the variables that are global. It can't provide much help in the way of assisting in profiling, aside from doing the aforementioned lookups.

What is the difference between a PS3 .elf and file and .self file?

A SELF file (Signed ELF) itself is really just an ELF that has a Sony header prefixed to it. Similarly a .sprx file is a .prx file with a Sony header prefixed to it.

What are the meanings of the cryptic acronyms used in .map (etc.) files?

Acronym Meaning
.bss Refers to a section which contains zero-initialized static/global variables. BSS means Block Started by Symbol. Refers to See http://en.wikipedia.org/wiki/.bss
.data Refers to a section which contains the pre-initialized data used for the program
got Refers to the Global Offset Table found on PowerPC. It is an array of pointers to addresses of symbols used by some block of code. Superceded by TOC. See http://www.ibm.com/developerworks/linux/library/l-powasm2.html
.init Refers to a section which contains functions run on init, before main.
.opd Refers to a section which contains "official procedure declarations" which are used to assist in linking functions and specifying the entry point to a program (the entry point is the first instruction in the code to be executed). Typically found only on RISC architectures such as PowerPC.
.text Refers to a section which contains the actual code (historically known as the program text)
toc Refers to the Table of Contents found on PowerPC. TOC is an array of pointers to symbols used by some block of code. Supercedes GOT. See http://www.ibm.com/developerworks/linux/library/l-powasm2.html
.rodata Refers to a section which contains read-only data.

How do I do lookups for Windows DLLs?

DLL (Dynamic Link Libraries) and libraries which are loaded at runtime instead of built-in at compile time. Since they are dynamically loaded, their code might be loaded into an arbitrary location in memory at runtime, though each DLL has a "preferred" load address which is used if nothing else is already at that location. Since the load address is determined at runtime, you can't know how to translate a callstack address into the function it refers to without knowing where in memory the DLL was loaded. EACallstack expects that when you register a symbol file (e.g. .pdb, .map) you supply the base address where the associated code (e.g. .exe, .xex) was loaded into memory.

While the code in a DLL can be loaded into an arbitrary location in memory at runtime, the symbol information in the .map/.pdb file stores addresses for symbols as if the DLL were loaded at the default "preferred" DLL base address. But at runtime a callstack address from the DLL will be based on where the DLL was loaded into memory. For example, a symbol in the .map file which is at address 0x00403000 could be at 0x00423000 at runtime if the DLL base address ends up being 0x00420000 instead of the default 0x00400000.

As a result of this, symbol databases for DLLs (e.g. EACallstack's MapFileMSVC or PDBFile) have a SetBaseAddress function which can be called in order to specify where the the DLL got located in memory. How do you tell what the base addresses are which you need to pass to SetBaseAddress? The answer to this depends on whether you are doing online lookups or offline lookups.

See the Online lookups and Offline lookups below in the PS3 PRX section for this. The situation for DLLs is almost identical to the situation for PRXs.

How do I do lookups for PS3 PRXs?

A PRX (PlayStation Relocatable) is like a Microsoft DLL for the PS3. The fact that it's relocatable means that its code might be loaded into an arbitrary location in memory at runtime. A result of this is that you can't know how to translate a callstack address into the function it refers to without knowing where in memory the PRX was loaded. This is the same as with Microsoft DLLs. EACallstack expects that when you register a symbol file (e.g. .map, .elf, .self, prx, .sprx) you supply the base address where the associated code (e.g. .elf, .self, .prx, .sprx) was loaded into memory.

Symbol information for a PRX is the same as for a PS3 ELF. Symbol information can be read from a .map file, or it can be read from the debug information present in the .prx or .sprx file. A .prx file is really just an ELF file but just named with a different file extension. Similarly, a .sprx file is really just a SELF file with a different file extension. While the code in a PRX can be loaded into an arbitrary location in memory at runtime, the symbol information in the .map/.prx/.sprx file stores addresses for symbols as if the PRX were loaded at a memory address of 0x00000000. In other words, the addresses are relative to the beginning of the PRX's beginning instead of expressed as absolute addresses on the PS3. But at runtime a callstack address from the PRX will be based on where the PRX was loaded into memory. For example, a symbol in the .map file which is at address 0x00003000 will be at 0x00603000 at runtime if the PRX base address ends up being 0x00600000. In order to look up the address in a .map file, you need to subtract 0x00600000 from the address in order to make it relative to the addresses in the .map file.

As a result of this, symbol databases for PRXs (e.g. EACallstack's MapFileGCC or DWARF3File) have a SetBaseAddress function which can be called in order to specify where the the PRX got located in memory. How do you tell what the base addresses are which you need to pass to SetBaseAddress? The answer to this depends on whether you are doing online lookups or offline lookups.

Online lookups

My online lookups, we mean address lookups of an application's own code addresses as it's running. For a MapFile to do a lookup of an address that originates from the main application elf, its base address can just default to 0x00000000 and lookups will work. For a MapFile to do a lookup of an address that originates from a PRX, you can let the MapFile automatically detect what the base address is in its Init function, or you need to call the MapFile SetBaseAddress function manually. MapFile will be able to automatically detect the base address in its Init function if the map file's file name (e.g. EAWebKit.map) is the same as the prx file name (e.g. EAWebKit.prx) and if the PRX itself has been loaded prior to when the MapFile Init function is called. You should call pAddressLookup->SetOption(kOptionOfflineLookup, 0) before calling MapFile Init to ensure that it does an automatic detect of the base address, though currently this setting defaults to 0 anyway.

In the case of manually calling SetBaseAddress, you need to determine the base address for the given PRX. You can do it upon loading the PRX via the following code:

EA::Callstack::AddressRepLookupSet gLookupSet; 
     
sys_prx_id_t moduleId    = sys_prx_load_module(prxFilePath, 0, NULL);
uint64_t     baseAddress = EA::Callstack::GetModuleBaseAddressByHandle(moduleId);
   
gLookupSet.AddDatabaseFile(prxMapFilePath, baseAddress);
gLookupSet.GetAddressRepLookup(prxMapFilePath)->SetOption(kOptionOfflineLookup, 0);

Or you can do it later via the following code:

EA::Callstack::AddressRepLookupSet gLookupSet; 
     
// Recall that MapFile is an instance of IAddressRepLookup.
IAddressRepLookup* pLookup     = gLookupSet.GetAddressRepLookup(prxMapFilePath);
uint64_t           baseAddress = EA::Callstack::GetModuleBaseAddress(prxMapFilePath);
    
pLookup->SetOption(kOptionOfflineLookup, 0);
pLookup->SetBaseAddress(baseAddress);

One thing you can't successfully do is adjust callstack addresses before doing lookups as an alternative to calling SetBaseAddress. EACallstack has a GetModuleBaseAddressByAddress function which could be used to do this, but doing this won't work because the adjusted callstack addresses will all be low values and all of them will work for any MapFile (or DWARF3File) instance. You'd get a bunch of incorrect symbols returned.

Offline lookups

By offline lookps, we mean address lookups being done on a PC for applications that are currently running or have previously run on another machine. The problem is that you need to call SetBaseAddress on any MapFiles or DWARF3Files (i.e. AddressRepLookups) associated with PRXs, but the application is usually no longer running. Unlike Windows DLLs, there's no mechanism on PS3 to force a PRX to load at some predetermined address, nor is there the concept of a default load address like there is with Windows DLLs. Nor can the callstack addresses generated by the app be pre-adjusted on the app's side while it runs, for the reason described in the paragraph above.

As a result, the only solution is for the runtime application to somehow publish the DLL base addresses so that the offline application (usually a PC app) can setup the AddressRepLookups with the correct base address. This situation exists not just for PRXs but also for Microsoft DLLs. The application can write this to a debug stream, a disk file, a network socket, etc. As of this writing EACallstack doesn't provide a built-in mechanism to do this, as such a thing tends to be fairly application-specific. The ExceptionHandler package does report the PRX base addresses in its exception reports, and EACallstack's PS3DumpFile reports PRX base addresses in its output.

ExceptionHandler report PRX base address output:

[Modules]
   base 0x10050000 size 0x00010430 entry 0x10050000 liblv2                /dev_flash/sys/external/liblv2.sprx
   base 0x10080000 size 0x00002dc0 entry 0x10080000 cellSysmodule_Library /dev_flash/sys/external/libsysmodule.sprx
   base 0x100a0000 size 0x0001b6b0 entry 0x100a0000 cellSysutil_Library   /dev_flash/sys/external/libsysutil.sprx
   .
   . 

PS3DumpFile report PRX base address output:

PRX data
  liblv2                PRX ID: 0x23000000 Code base address: 0x00300000 Code size: 0x2000 Version: 257 Path: "/dev_flash/sys/external/liblv2.sprx" 
  cellSysmodule_Library PRX ID: 0x23001000 Code base address: 0x00310000 Code size: 0x1600 Version: 257 Path: "/dev_flash/sys/external/libsysmodule.sprx"   cellSysutil_Library   PRX ID: 0x23002000 Code base address: 0x00320000 Code size: 0x2000 Version: 257 Path: "/dev_flash/sys/external/libsysutil.sprx"
  .
  .

The application can print module info as it loads PRXs with something like the following:

sys_prx_id_t moduleId    = sys_prx_load_module(prxFilePath, 0, NULL);
uint64_t     baseAddress = EA::Callstack::GetModuleBaseAddressByHandle(moduleId);
 
printf("PRX Load: \"%s\" 0x%08x\n", prxFilePath, (unsigned)baseAddress);

The application can print module info later during execution with the following:

EA::Callstack::ModuleInfo moduleInfoArray[32]; // Watch out that too many of these on the stack can exhaust stack memory. 
   
size_t count = EA::Callstack::GetModuleInfo(moduleInfoArray, 32);
 
for(size_t i = 0; i < count; ++i) // In practice we should call GetModuleInfo(NULL, 0) to get the required size. 
{
    printf("PRX Load: \"%s\" 0x%08x\n", moduleInfoArray[i].mPath.c_str(), (unsigned)moduleInfoArray[i].mBaseAddress);
} 

An application that does offline lookups for an app with PRXs would do something like the following:

EA::Callstack::AddressRepLookupSet gLookupSet;
PRXInfoArray gPRXInfoArray; // This is an array filled in with the data printed by the offline application. 
     
// We iterate all the PRX Load entries from the application output. 
for(int i = 0; i < gPRXInfoArray.size(); i++)
{
    gLookupSet.AddDatabaseFile(gPRXInfoArray[i].mpMapFilePath, gPRXInfoArray[i].mBaseAddress);
    gLookupSet.GetAddressRepLookup(gPRXInfoArray[i].mpMapFilePath)->SetOption(EA::Callstack::kOptionOfflineLookup, 1);
} 

Why isn't my XBox 360 callstack functionality working right?

The most common cause of this is that you are not defining EA_XBDM_ENABLED = 1 in your build. EA_XBDM_ENABLED is set to 1 by default in debug builds only. This is because final builds cannot use the xbdm library, and so EACallstack requires the user to explicitly enable xbdm in order to use it.

Why is my XBox 360 callstack showing up in the debugger with no entries?

This is usually caused by the excessively large jump support Microsoft added to the compiler to make incremental linking work with big executables. Disable incremental linking and enable comdat folding and it goes away. Solution by Kevin Perry.

I get crashes on Microsoft 64 bit platforms within RtlVirtualUnwind.

It turns out that using alloca somewhere in your callstack can sometimes cause RtlVirtualUnwind to crash. It's not clear if this is the fault of EACallstack (due to not providing a full context) or if it's truly a bug in RtlVirtualUnwind. Until some workaround is found within EACallstack, you can disable your alloca usage to work around this.

The functions reported for the callstack seem senseless.

If GetCallstack returned what looks like reasonable addresses, but when translated to symbols seems senseless, there are two common causes:

The first case above is straightforward, but the second case requires some explaining. Some of it is explained already above in two DLL-related sections.

/DYNAMICBASE:NO

 

DLL (Dynamic Link Libraries) and libraries which are loaded at runtime instead of built-in at compile time. Since they are dynamically loaded, their code might be loaded into an arbitrary location in memory at runtime, though each DLL has a "preferred" load address which is used if nothing else is already at that location. Since the load address is determined at runtime, you can't know how to translate a callstack address into the function it refers to without knowing where in memory the DLL was loaded. EACallstack expects that when you register a symbol file (e.g. .pdb, .map) you supply the base address where the associated code (e.g. .exe, .xex) was loaded into memory.

While the code in a DLL can be loaded into an arbitrary location in memory at runtime, the symbol information in the .map/.pdb file stores addresses for symbols as if the DLL were loaded at the default "preferred" DLL base address. But at runtime a callstack address from the DLL will be based on where the DLL was loaded into memory. For example, a symbol in the .map file which is at address 0x00403000 could be at 0x00423000 at runtime if the DLL base address ends up being 0x00420000 instead of the default 0x00400000.

As a result of this, symbol databases for DLLs (e.g. EACallstack's MapFileMSVC or PDBFile) have a SetBaseAddress function which can be called in order to specify where the the DLL got located in memory. How do you tell what the base addresses are which you need to pass to SetBaseAddress? The answer to this depends on whether you are doing online lookups or offline lookups.

See the Online lookups and Offline lookups below in the PS3 PRX section for this. The situation for DLLs is almost identical to the situation for PRXs.

 


End of document