Skip to content

Fix MyThread NULL _reent pointer - #2263

Open
LeonLeBreton wants to merge 1 commit into
LumaTeam:masterfrom
LeonLeBreton:fix/mythread_crash
Open

Fix MyThread NULL _reent pointer#2263
LeonLeBreton wants to merge 1 commit into
LumaTeam:masterfrom
LeonLeBreton:fix/mythread_crash

Conversation

@LeonLeBreton

Copy link
Copy Markdown

Hi, while playing around with the Rosalina source code, I noticed that using any stdio function that format strings (like sprintf, snprintf, etc.), when we want to formats something, make the console crash (so this is ok: snprintf(buf, sizeof(buf), "OK");, and this make the console crash: snprintf(buf, sizeof(buf), "CRASH %u", 1u);).

After long research, I found out that the problem is that is because of MyThread.c that don't initialize the TLS variables correctly.

libctru/source/internal.h

typedef struct
{
	// Magic value used to check if the struct is initialized
	u32 magic;

	// Pointer to the current thread (if exists)
	Thread thread_ptr;

	// Pointer to this thread's newlib state
	struct _reent* reent;

	// Pointer to this thread's thread-local segment
	void* tls_tp; // !! Keep offset in sync inside __aeabi_read_tp !!

	// FS session override
	u32    fs_magic;
	Handle fs_session;

	// Whether srvGetServiceHandle is non-blocking in case of full service ports.
	bool srv_blocking_policy;
} ThreadVars;

reent, need for newlib to work correctly, is not initialized in MyThread.c, so when we call snprintf with a format string that needs to access the reent structure, it crashes because the pointer is NULL.

So I modified MyThread.c to initialize the reent pointer using (u32)_impure_ptr, and now snprintf works correctly. (I only added that, but the best would be to initialize the whole structure correctly).

If you want to test the crash, here is a simple snippet that you can add to the Rosalina menu.c:

# #include "luma_config.h"
# 
# #include <stdio.h>
+ static void crasher_proof(void)
+ {
+     char buf[16];
+     snprintf(buf, sizeof(buf), "CRASH %u", 42u);
+     (void)buf;
+ }
#
# Menu rosalinaMenu = {
#     "Rosalina menu",
#     {
+        { "[TEST] Crash proof", METHOD, .method = &crasher_proof },
#        { "Take screenshot", METHOD, .method = &RosalinaMenu_TakeScreenshot },

Trigger the entry immediately crash the console without the fix, and with the fix it works correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant