Hi,
I have some issues regarding debugging SDL apps. I know that linking with SDLmain redirects stdout and stderr to two files in the current directory. Now, if I run SDL app via PSP XMB these files are created where the EBOOT.PBP is placed, but they are empty (size 0), eventhough I use fprintf/printf to write to stderr/stdout. Not only is it strange that these files are empty, they shouldn't exist in the first place, because the code in SDLmain removes them if they are empty. If I run the SDL app via PSPlink, then the files are created (or properly removed if empty) where the target.elf is located (host0:). I assumed it's an issue with a memory stick, but if I open a file and fprintf to it, it works as expected.
I would have used the PSPlink and had proper redirection (and other neat stuff provided by this great utility), but I find it only works with small projects; whenever I work with a bigger project (for instance porting an SDL game) it starts the app, but resets soon afterwards (without an error).
Currently my only option is to run SDL app via PSP XMB and print directly to the file. It's a burden, because using PSPlink is much more convenient and I have to change the output logic from an app I port, which I find redundant.
Actually I can live with that, but somehow I guess there must be an easier way, I am just not doing something right.
BTW, I am using kernel 1.50 (via OE 3.40) and it doesn't matter if the app is compiled with C or C++ compiler (I've seen a post claiming problems with C++ compiler and SDL's stdout/stderr redirection).
Debugging SDL apps
Hmm, I don't know the answer. How are you exiting the game? If you're calling something like sceKernelExitGame instead of just returning from main normally, the atexit-registered handler cleanup_output won't be called and you won't close the files properly, which could explain the 0-byte size.
I don't know why psplink would give you trouble, maybe you're running low on RAM with the bigger app? You could also try using real 1.50 and not custom firmware just to make sure there's no issue there.
I don't know why psplink would give you trouble, maybe you're running low on RAM with the bigger app? You could also try using real 1.50 and not custom firmware just to make sure there's no issue there.
Jim,
I exit the game either by returning from main or by using exit (home button). You can check that the redirection doesn't work (from XMB) with something as simple as Hello World app:
I also suspect the RAM or CFW might be giving problems to psplink. I'll revert to FW 1.5, but not any time soon, I rather spend my time programming than flashing. :)
I exit the game either by returning from main or by using exit (home button). You can check that the redirection doesn't work (from XMB) with something as simple as Hello World app:
Code: Select all
#include <stdio.h>
#include <SDL.h>
#ifdef __cplusplus
extern "C"
#endif
int main(int argc, char *argv[])
{
fprintf(stderr, "Hello world.\n");
printf("Hello world.\n");
SDL_Delay(1000);
return 0;
}
Tyranid,
Actually, I am using kernel mode (default SDLmain). I have read somewhere it is required to redirect output. Now that I think of it, I guess using these CRT routines shouldn't require kernel mode, only installing exception handler might (which psplink installs anyway). I'll switch to the user mode and see what happens. Anyway, what issues might kernel mode cause to psplink?
Another question not related to psplink. If the SDL application suddenly exits to XMB without exception handler being called, am I right to assume I might have problems with stack overrun or are the buffer under/over-runs catched by exception handler?
Actually, I am using kernel mode (default SDLmain). I have read somewhere it is required to redirect output. Now that I think of it, I guess using these CRT routines shouldn't require kernel mode, only installing exception handler might (which psplink installs anyway). I'll switch to the user mode and see what happens. Anyway, what issues might kernel mode cause to psplink?
Another question not related to psplink. If the SDL application suddenly exits to XMB without exception handler being called, am I right to assume I might have problems with stack overrun or are the buffer under/over-runs catched by exception handler?
Bulb:
Well redirecting stdout/stderr very much depends on how you are writing to them. SDL just reopens stdout and stderr using the stdio library, then if you call printf/fprintf etc you will actually write to the files themselves and not to the actual destination. However if you called sceIoWrite(STDOUT_FILENO, ...) then you would not catch the output. At any rate surely one of the points in using psplink is the fact that stdout/stderr is already handled for you, if you need to write debug output to a file you are probably safest to open a new file with fopen and fprintf to it.
As for playing with kernel apps in psplink the main issue is down to memory. I have done as much as I can to limit psplink's memory footprint but it isn't small, and as time has gone on the amount of free kernel memory has dropped to like 80k or so after psplink is loaded. Just loading a kernel ELF in that space will kill it, but you can debug alot of kernel plugins if you are careful about it. But with psplink all in kernel mode you get 100% of user memory available to you which is the whole point.
And as for why the app exits I don't know. If you get a stack overrun then the kernel will kill your thread dead. If you are getting buffer overruns/underruns it will depend what happens, if you smash the RA value then you could jump into garbage and the exception handler should catch you, otherwise you might just get random crashes.
Well redirecting stdout/stderr very much depends on how you are writing to them. SDL just reopens stdout and stderr using the stdio library, then if you call printf/fprintf etc you will actually write to the files themselves and not to the actual destination. However if you called sceIoWrite(STDOUT_FILENO, ...) then you would not catch the output. At any rate surely one of the points in using psplink is the fact that stdout/stderr is already handled for you, if you need to write debug output to a file you are probably safest to open a new file with fopen and fprintf to it.
As for playing with kernel apps in psplink the main issue is down to memory. I have done as much as I can to limit psplink's memory footprint but it isn't small, and as time has gone on the amount of free kernel memory has dropped to like 80k or so after psplink is loaded. Just loading a kernel ELF in that space will kill it, but you can debug alot of kernel plugins if you are careful about it. But with psplink all in kernel mode you get 100% of user memory available to you which is the whole point.
And as for why the app exits I don't know. If you get a stack overrun then the kernel will kill your thread dead. If you are getting buffer overruns/underruns it will depend what happens, if you smash the RA value then you could jump into garbage and the exception handler should catch you, otherwise you might just get random crashes.
Tyranid,
Thanks for explanation of redirection, I've already known that much. However I do not understand why it doesn't work without psplink (launching directly from XMB).
Seems I'll be using custom SDLmain from now on. :)
If the app overruns the stack and kernel kills the thread, is it possible to somehow get information about that? The value of program counter (which might be garbage) would be nice to get, too. :)
Thanks for explanation of redirection, I've already known that much. However I do not understand why it doesn't work without psplink (launching directly from XMB).
Seems I'll be using custom SDLmain from now on. :)
If the app overruns the stack and kernel kills the thread, is it possible to somehow get information about that? The value of program counter (which might be garbage) would be nice to get, too. :)
If you have a serial cable then yes, when the kernel discovers a stack overflow it will dump the current state of the thread to Kprintf and then stop the thread. Because of where it is doing it you cannot use something like usbkprintf but you could write it to the screen somewhere.
The other alternative would be for some piece of code to check the thread state, there is a specific "KILLED" state which means the kernel forced the thread to stop due to a stack overflow. You can see it in psplink but you would have to do it manually otherwise.
The other alternative would be for some piece of code to check the thread state, there is a specific "KILLED" state which means the kernel forced the thread to stop due to a stack overflow. You can see it in psplink but you would have to do it manually otherwise.