Welcome! Log In Create A New Profile

Advanced

fopen in a thread with no console = freeze

Posted by DrTwox 
fopen in a thread with no console = freeze
October 24, 2009 05:05AM
I'm not really sure what's going on here... fopen, when called from a thread, when there is no console initialized, will freeze the Wii.

Here is a small test app I cut down to the bare essentials that demonstrates the problem. A compiled version (devkitPPC r18 and libogc 1.8.0) is linked below.
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define FILE_NAME "sd:/testfile.txt"

////////////////////////////////////////////////////////////////////////////////
// VIDEO INIT
////////////////////////////////////////////////////////////////////////////////
static void *xfb = NULL;
static GXRModeObj *rmode = NULL;
static void init_video() {
	VIDEO_Init();
	rmode = VIDEO_GetPreferredMode(NULL);
	xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
	console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
	VIDEO_Configure(rmode);
	VIDEO_SetNextFramebuffer(xfb);
	VIDEO_SetBlack(FALSE);
	VIDEO_Flush();
	VIDEO_WaitVSync();
	if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
}

////////////////////////////////////////////////////////////////////////////////
// THREAD
////////////////////////////////////////////////////////////////////////////////
#define THREAD_PRIO 90
#define THREAD_STACK_SIZE 1024*8
static lwp_t thread = LWP_THREAD_NULL;
static u8 stack[ THREAD_STACK_SIZE ];

static void *thread_main( void *unused ) {
_break();
	FILE *handle = fopen( FILE_NAME, "rb" );
	/* if init_video wasn't called in main(), the above call to fopen will
	 * freeze the Wii and the follow breakpoint will never be reached */
_break();

	if ( handle == NULL ) {
		return NULL;
	}

	fclose( handle );

	return NULL;
}

////////////////////////////////////////////////////////////////////////////////
// MAIN
////////////////////////////////////////////////////////////////////////////////
int main() {
	DEBUG_Init( GDBSTUB_DEVICE_USB, 1 );
	_break();

	/* If init_video() is not called, the Wii will freeze at the
	 * fopen() call in thread_main() */
	init_video();

	fatInitDefault();

	/* Create the thread that calls fopen */
	if ( LWP_CreateThread( &thread, thread_main, NULL, stack, THREAD_STACK_SIZE, THREAD_PRIO ) != 0 ) {
		exit( EXIT_FAILURE );
	}

	WPAD_Init();

	while(1) {

		WPAD_ScanPads();
		u32 pressed = WPAD_ButtonsDown(0);
		if ( pressed & WPAD_BUTTON_HOME ) exit(0);

		VIDEO_WaitVSync();
	}

	return 0;
}
Download: fopen.tar.bz2

As commented in the code, if I call init_video() from within main, fopen functions correctly. If init_video() is omitted, fopen in thread_main() will freeze the Wii. Here's the output from gdb with init_video() removed from main().

GNU gdb (GDB) 7.0
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later [gnu.org]
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu --target=powerpc-eabi".
For bug reporting instructions, please see:
[www.gnu.org]...
0x80037544 in ?? ()
Reading symbols from /home/drtwox/wiidev/tests/fopen/fopen.elf...done.
(gdb) bt
#0 0x80037544 in _break ()
#1 0x80007544 in main () at /home/drtwox/wiidev/tests/fopen/source/main.c:59
(gdb) cont
Continuing.
[New Thread 3]

Program received signal SIGTRAP, Trace/breakpoint trap.
[Switching to Thread 3]
0x80037544 in _break ()
(gdb) bt
#0 0x80037544 in _break ()
#1 0x800075bc in thread_main (unused=0x0) at /home/drtwox/wiidev/tests/fopen/source/main.c:39
#2 0x8001d2ec in __lwp_thread_handler ()
#3 0x8001d28c in __lwp_thread_exit ()
(gdb) cont
Continuing.

And that's as far as it gets, the breakpoint after fopen is never reached.

Edit: If I at least call VIDEO_Init() the problem goes away... why?



Edited 3 time(s). Last edit at 10/24/2009 05:34AM by DrTwox.
Re: fopen in a thread with no console = freeze
October 24, 2009 07:57AM
Do you see any change if you declare FILE *handle as global?

Also I don't think you need to void *stackbase param in the create thread. Try :- LWP_CreateThread( &thread, thread_main, NULL, NULL, THREAD_STACK_SIZE, THREAD_PRIO ).

Just some ideas :)
Re: fopen in a thread with no console = freeze
October 24, 2009 03:54PM
VIDEO_WaitVSync() relies on VIDEO_Init() being called.
Re: fopen in a thread with no console = freeze
October 30, 2009 10:42PM
I think I'll attribute this problem to general bone-headedness :) The problem was as Michael said, without VIDEO_Init, VIDEO_WaitVSync would freeze, not fopen. Thank you both for the help... if only I could delete these embarrassing posts!
Sorry, only registered users may post in this forum.

Click here to login