First: this is not my code, I simply got the code from crazyc and SamuraiX and made it easy to use (at least for me). ;)
Original thread: http://forums.ps2dev.org/viewtopic.php?t=9564
Maybe it's usefull for someone else...
What is this?
This is a prx to handle exception on PSP, when an exception is raised some usefull information are shown on the display (and can be dumped to a text file).
How to compile it
Enter the prx directory and simply type
Why do you use your own exception code (well actually just taken from other sources anyway) when you can just call pspDebugInstallErrorHandler from the sdk, geez some people :P
TyRaNiD wrote:Why do you use your own exception code (well actually just taken from other sources anyway) when you can just call pspDebugInstallErrorHandler from the sdk, geez some people :P
Sorry, I saw crazyc code and thought that pspDebugInstallErrorHandler wasn't working on newer firmwares (the sdk sample is 1.50 only) but didn't test it.
If pspDebugInstallErrorHandler works on all firmware than the prx can be simpler. :)
TyRaNiD wrote:Why do you use your own exception code (well actually just taken from other sources anyway) when you can just call pspDebugInstallErrorHandler from the sdk, geez some people :P
Are you sure? I'm fairly sure it won't work unless you can load a kernel PRX into the user memory partition, which admittedly I didn't try, because pspDebugInstallErrorHandler erets to _pspDebugTrapEntry, which will be part of the prx. If the exception occurs in user mode, the eret will return to user mode but _pspDebugTrapEntry will be in the kernel partition. Also, 3.71 mixes the nid for sceKernelRegisterDefaultExceptionHandler.
SNES9xTYL has pspDebugInstallErrorHandler in its init code, but it had to be disabled with #ifdef to get the app to work in 3.xx. You cannot successfully call that function from a user mode prx in 3.xx - at least not from what I've seen. Having this as a prx with a simple init call to set it up is better for apps in any case. That allows the exception handling to be independent of the app, and simple to use in the app. If any more changes occur with the exception handling, it also means that it can be handled merely by changing the prx and not the entire app.
I plan to start using this in all my stuff. Many thanks to crazyc and sakya for this useful tool. :)
If I remember correctly it wasn't the fact you couldn't use pspDebugInstallErrorHandler(). It was the fact that you couldn't use pspDebugScreenPrintf() in a kernel mode prx for the dump. There would be linker errors for missing libraries for debug printing to screen.
to your ExceptionHandler to print the offset of the exception to the start of the text section as the relocated addresses are kind of useless.
I'm a little confused. I've purposely created an exception and the RA value pointed to the last call prior to the exception and the EPC value was pointing at the exception itself. Now could you explain a little further on why we would need the start of the text section? Also why do you label the module with '.text' ? Why would the relocated address be useless?
When I added the additional printing above the result did not make sense to me.
to your ExceptionHandler to print the offset of the exception to the start of the text section as the relocated addresses are kind of useless.
I'm a little confused. I've purposely created an exception and the RA value pointed to the last call prior to the exception and the EPC value was pointing at the exception itself. Now could you explain a little further on why we would need the start of the text section? Also why do you label the module with '.text' ? Why would the relocated address be useless?
When I added the additional printing above the result did not make sense to me.
just use psp-objdump/prxtool for disassembly code, and you'll understand why crazyc's advise is a good one and cheap to do so (just a line to add).
This is probably an unrelated question. But is this installable exception handler a "true" exception handler for Allegrex (which suggests it can handle all exceptions/traps like clock interrupt or data/instruction bus error), or just one of the cascaded exception handlers managed by the firmware's exception/trap subsystem?
I am asking this because I saw there were code preserving the CPU status at the beginning of the handler, and if it was a cascaded handler it probably would not need to do so as the firmware's trap subsystem would have had the status preserved instead and passed it to our installed handlers, I guess.
No you need to handle the register saving yourself the kernel doesn't do it for you even though this uses the default exception handler.
Basically other types of exception handle register saving in the different ways, for example a syscall doesn't really need to preserve anything bar enough to get it to return.
but this doesen't seem to help me (I don't know ASM...). How can I trace the exception to understand where it's raised?
And another question...
I tried to compile my app with -g to use psp-addr2line to get the line of code which raised the exception (if I understant well) but I get this errors:
system/exception.o: In function `ExceptionHandler':
system/exception.c:47: relocation truncated to fit: R_MIPS_GPREL16 against `_ftext'
system/exception.c:67: relocation truncated to fit: R_MIPS_GPREL16 against `_ftext'
gui/menu.o: In function `drawMenu':
gui/menu.c:112: relocation truncated to fit: R_MIPS_GPREL16 against `osl_curFont'
gui/menu.c:99: relocation truncated to fit: R_MIPS_GPREL16 against `osl_curFont'
gui/menu.c:108: relocation truncated to fit: R_MIPS_GPREL16 against `osl_curFont'
gui/common.o: In function `drawToolbars':
gui/common.c:158: relocation truncated to fit: R_MIPS_GPREL16 against `osl_curFont'
gui/common.o: In function `drawButtonBar':
gui/common.c:194: relocation truncated to fit: R_MIPS_GPREL16 against `osl_curFont'
gui/common.o: In function `drawConfirm':
gui/common.c:272: relocation truncated to fit: R_MIPS_GPREL16 against `osl_curFont'
gui/common.o: In function `drawWait':
gui/common.c:289: relocation truncated to fit: R_MIPS_GPREL16 against `osl_curFont'
gui/common.o: In function `drawHelp':
gui/common.c:327: relocation truncated to fit: R_MIPS_GPREL16 against `osl_curFont'
gui/gui_fileBrowser.o: In function `drawUSBmessage':
gui/gui_fileBrowser.c:52: additional relocation overflows omitted from the output
collect2: ld returned 1 exit status
psp-make: *** [lightmp3.elf] Error 1
Esecuzione terminata
moonlight wrote:a breakpoint exception? That is usually done by an application on purpose, or generated by the compiler when there is a division by zero.
Many thanks, I solved the problem thanks to your advice. :)
I didn't understand what can cause a "beakpoint" (sounded strange to me).
It was a division by zero (wasn't difficult to find it now I know what to search for). :)
exception/exception.o: In function `ExceptionHandler':
exception.c:(.text+0xa8): relocation truncated to fit: R_MIPS_GPREL16 against `_ftext'
collect2: ld returned 1 exit status
make: *** [make.elf] Error 1
Those kinds of errors tend to be from the small data segment. If you see something like -G8 in your makefile, that's telling the compiler to try to put everything <= 8 bytes in size into the small data segment. This doesn't work very well on newer versions of gcc, so you see -G0 on many projects today.
That's a really non-standard PSP project makefile. :)
I noticed you have both -G4 and -G0 in the CFLAGS line. Remove the -G4 and see what happens - I don't know which would have priority, the -G4 or the -G0. Just use one.
so is there no solution for this and if it helps i'm using cpp for the whole project but this file is .c i externed the initExceptionHandler() function so that it would be c
Sakya, would you recommend me to use your prx for my use case?
I have lots of stupid crashes in my application. It heavily relies on external content and I cannot control everything. I want my game to smoothly handle errors, and quit, rather than crash + having to reboot the PSP.