My SDL2 game crash at launch, how to debug it?

QuestionSleep1984

Member
OP
Newcomer
Joined
Jun 10, 2019
Messages
17
Trophies
0
Age
26
Location
Inside of the Great Deku Tree
XP
452
Country
Mexico
Hello everyone, as the title says, I'm porting my sdl2 game to switch and in my first try it builds fine but it crashed at launch.
How can I figure out what's wrong? I know I can use outputs to console using nxlink but it doesn't work.

Thanks in advance. :yayswitch:
 
Joined
Sep 9, 2019
Messages
878
Trophies
1
Location
Switch scene
Website
github.com
XP
2,488
Country
Korea, North
If you run the game in applet mode it will cause the entire firmware to fatal. That will give you an error code which you can search through in here. https://switchbrew.org/wiki/Error_codes#Fatal_Errors
Hopefully that will be enough.

If that is not enough you can use addr2line. Credits to @shchmue for explaining how this works in the AtlasNX dev chat.
To paraphrase what was said in the chat logs addr2line will take an address and tell you which line of code it maps to. You just have to take the last address from the stack before the crash and see which line maps to it.
You use this command:
Bash:
aarch64-none-elf-addr2line -e yourprogram.elf -f -p -C -a youroffset
Replace "yourprogram" with the name of your program (E.g in my case when I build Amiigo I get Amiigo.nro, so if I ran this on Amiigo I would put Amiigo.elf instead of yourprogram.elf)
Replace youroffset with the address. E.g 0x6d604
To get the address take the value in the PC register (program counter) and subtract the base address of your program. How do you get those values? When your program crashes a dump of all that info will be generated in sdmc:/atmosphere/fatal_reports (this info will also be on the fatal error screen but imo it's much easier to copy paste it than type it all out manually).

I have put a screenshot of a crash report below. In this case take PC (000000485d056714) and subtract Start Address (000000485ce00000) this will result in (0x)256714. This crash was generated by a system app but if we pretend it came from Amiigo and I wanted to know which line of code caused the crash I would type
Bash:
aarch64-none-elf-addr2line -e Amiigo.elf -f -p -C -a 0x256714

2022050812184400-F1C11A22FAEE3B82F21B330E1B786A39.jpg


If the line of code that caused the crash came from some library you're using you might need to look at a different address. Each line in the stack trace refers to the return address of each function on the stack. If I recall correctly it is the exact same process to obtain those addresses as it is to get the line that it crashed on. I.e ReturnAddress[XX] - Start Address.

This might sound difficult but it really isn't. The biggest pain in the ass is trying to copy over the crash log after you crashed. For that reason I usually stick to using error codes and trying to deduce what caused the crash from those, but if you get really stuck using addr2line can be very useful.

Edit: You mentioned NX-Link wasn't working. For debugging using NX-Link make sure that you're calling all of the init functions that you need. I can't remember exactly what they are but I think you need to init the sockets system module and NXLink itself. Then you need to send the NRO to the Switch using NXLINK with the -S argument.

Edit 2: Going off of what I have in Amiigo https://github.com/CompSciOrBust/Amiigo/blob/master/source/main.cpp#L9
I think you need to call socketInitializeDefault() and nxlinkStdio(), possibly nifmInitialize(NifmServiceType_User) but I don't think that's needed. Be sure to call socketExit() before the app closes. When I send the app to my switch I use:
Bash:
nxlink -s Amiigo.nro
Make sure that you have NX-Link open in HB Menu on your Switch by pressing Y. If NX-Link can not find your Switch you may need to provide the IP address using the -a argument.

Edit 3: If I had a random guess about why your game is crashing at stat up it is because you're probably forgetting to initialize something. From my own experience using SDL2 on Switch it is likely one of the following: TTF_Init(), plInitialize(), romfsInit().
TTF is for font loading, I think that's also used on Windows so probably not that if you game works fine on PC. plInitialize is for loading Nintendo's system font, probably not that if you're not using it. romfsInit is for loading files from RomFS. I think this is the most likely culprit if you're trying to embed assets in to the NRO file itself instead of loading them from the SD Card.
 
Last edited by CompSciOrBust,

QuestionSleep1984

Member
OP
Newcomer
Joined
Jun 10, 2019
Messages
17
Trophies
0
Age
26
Location
Inside of the Great Deku Tree
XP
452
Country
Mexico
What is its name, can you please explain a little more?
It doesn't have a name yet, but It will be a galaga clone. I'm still working on it.
For example GDB if you know how to use disassembler
I haven't use GBD but I will give it a try

If you run the game in applet mode it will cause the entire firmware to fatal. That will give you an error code which you can search through in here. https://switchbrew.org/wiki/Error_codes#Fatal_Errors
Hopefully that will be enough.
The fatal error it's the UndefinedInstruction (0xa8).
I have to say that this is not my first SDL2 port, when I was learning SDL2 I port some of the lessons to Switch, it was easy.

If that is not enough you can use addr2line. Credits to @shchmue for explaining how this works in the AtlasNX dev chat.
To paraphrase what was said in the chat logs addr2line will take an address and tell you which line of code it maps to. You just have to take the last address from the stack before the crash and see which line maps to it.
You use this command:
Bash:
aarch64-none-elf-addr2line -e yourprogram.elf -f -p -C -a youroffset
Replace "yourprogram" with the name of your program (E.g in my case when I build Amiigo I get Amiigo.nro, so if I ran this on Amiigo I would put Amiigo.elf instead of yourprogram.elf)
Replace youroffset with the address. E.g 0x6d604
To get the address take the value in the PC register (program counter) and subtract the base address of your program. How do you get those values? When your program crashes a dump of all that info will be generated in sdmc:/atmosphere/fatal_reports (this info will also be on the fatal error screen but imo it's much easier to copy paste it than type it all out manually).

I have put a screenshot of a crash report below. In this case take PC (000000485d056714) and subtract Start Address (000000485ce00000) this will result in (0x)256714. This crash was generated by a system app but if we pretend it came from Amiigo and I wanted to know which line of code caused the crash I would type
Bash:
aarch64-none-elf-addr2line -e Amiigo.elf -f -p -C -a 0x256714

View attachment 309198

If the line of code that caused the crash came from some library you're using you might need to look at a different address. Each line in the stack trace refers to the return address of each function on the stack. If I recall correctly it is the exact same process to obtain those addresses as it is to get the line that it crashed on. I.e ReturnAddress[XX] - Start Address.

This might sound difficult but it really isn't. The biggest pain in the ass is trying to copy over the crash log after you crashed. For that reason I usually stick to using error codes and trying to deduce what caused the crash from those, but if you get really stuck using addr2line can be very useful.
Thanks for the whole explanation, I'll give it a try to addr2line.

Edit: You mentioned NX-Link wasn't working. For debugging using NX-Link make sure that you're calling all of the init functions that you need. I can't remember exactly what they are but I think you need to init the sockets system module and NXLink itself. Then you need to send the NRO to the Switch using NXLINK with the -S argument.

Edit 2: Going off of what I have in Amiigo https://github.com/CompSciOrBust/Amiigo/blob/master/source/main.cpp#L9
I think you need to call socketInitializeDefault() and nxlinkStdio(), possibly nifmInitialize(NifmServiceType_User) but I don't think that's needed. Be sure to call socketExit() before the app closes. When I send the app to my switch I use:
Bash:
nxlink -s Amiigo.nro
Make sure that you have NX-Link open in HB Menu on your Switch by pressing Y. If NX-Link can not find your Switch you may need to provide the IP address using the -a argument.
Yeah I'm using the -s flag to start the server and I'm init the socket and nxlinkStdio().

Edit 3: If I had a random guess about why your game is crashing at stat up it is because you're probably forgetting to initialize something. From my own experience using SDL2 on Switch it is likely one of the following: TTF_Init(), plInitialize(), romfsInit().
TTF is for font loading, I think that's also used on Windows so probably not that if you game works fine on PC. plInitialize is for loading Nintendo's system font, probably not that if you're not using it. romfsInit is for loading files from RomFS. I think this is the most likely culprit if you're trying to embed assets in to the NRO file itself instead of loading them from the SD Card.
That was I was thinking, maybe I'm not loading correctly the files from RomFS.

Thanks everyone, I'll try to fix this.

EDIT: I fucked up my console XD After that fatal error, I can't load any game from the SD. Everything crash at launch.
 
  • Like
Reactions: mathew77

QuestionSleep1984

Member
OP
Newcomer
Joined
Jun 10, 2019
Messages
17
Trophies
0
Age
26
Location
Inside of the Great Deku Tree
XP
452
Country
Mexico
Is your SD Card formatted as ExFat or Fat32? The Switch OS has a bug which causes ExFat cards to become corrupt when using homebrew.
I use ExFat because it's a 128GB SD card, I already knew It could happen but I ignored it.
I fix it formatting the SD and starting from scratch but this time using Fat32.
 
  • Like
Reactions: CompSciOrBust
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Skelletonike @ Skelletonike:
    1H left, such a slow week.
  • Sonic Angel Knight @ Sonic Angel Knight:
    Okay, I had spaghetti :P
  • SylverReZ @ SylverReZ:
    Hope they made lots of spaget
  • K3N1 @ K3N1:
    Chill dog
  • SylverReZ @ SylverReZ:
    Chilli dog
  • Skelletonike @ Skelletonike:
    Damn, I'm loving the new zelda.
  • xtremegamer @ xtremegamer:
    loving the new zelda, i started a game, it was so fucking good, so i
    am waiting on my friend to get home so we can start a new one together
  • Skelletonike @ Skelletonike:
    I just dislike that they don't let me choose the voices before the game starts. Happened with botw as well, had to change to japanese and restart.
  • K3N1 @ K3N1:
    But the important question is can you choose gender
  • Skelletonike @ Skelletonike:
    Same way you can choose Gerald's gender.
  • Skelletonike @ Skelletonike:
    *Geralt, damn autocorrect.
  • Psionic Roshambo @ Psionic Roshambo:
    But can he be trans? Lol
  • K3N1 @ K3N1:
    Zelda transforms into link
  • Psionic Roshambo @ Psionic Roshambo:
    Link I'm not the princess your looking for.... *Pulls a crying game*
  • K3N1 @ K3N1:
    *skirt up* it's exactly what I always wanted
  • Skelletonike @ Skelletonike:
    Just scanned all my zelda amiibos, took a while but didn't get anything that cool, did get the lon lon ranch hylian fabrics though.
  • Skelletonike @ Skelletonike:
    It was pretty funny when I scanned wolf link and got a shit load of meat.
  • K3N1 @ K3N1:
    @Skelletonike, btw I ran that custom for mgs4 on the deck I'm amazed it got that far in game
  • K3N1 @ K3N1:
    Plug in*
  • K3N1 @ K3N1:
    Your favorite activity
  • BentlyMods @ BentlyMods:
    My fav actvity is:

    mario-dancing.gif
    BentlyMods @ BentlyMods: My fav actvity is: