Problem with PRX, freezes psp!

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
theHobbit
Posts: 65
Joined: Sat Sep 30, 2006 5:26 am

Problem with PRX, freezes psp!

Post by theHobbit »

Hi I'm having some trouble with prx's. I looked at the PSPRadio code and was doing some simple tests with a prx. But for some reason the app freezes when i use the new operator in the prx. This is the code:

The loader stuff:

// This is taken from the PSPRadio PRXLoader
PRXLoader.h

Code: Select all

#include <pspkernel.h>
	#include <psptypes.h>

	#define _PRXLOADER_
	
	class CPRXLoader
	&#123;
	public&#58;
		CPRXLoader&#40;&#41;;
		~CPRXLoader&#40;&#41;;
		int Load&#40;const char *filename&#41;;
		int Unload&#40;&#41;;
		int Start&#40;int argc = 0, char * const argv&#91;&#93; = NULL&#41;;
		bool IsLoaded&#40;&#41;  &#123; return m_IsLoaded; &#125;
		bool IsStarted&#40;&#41; &#123; return m_IsStarted; &#125;
		int  GetError&#40;&#41;  &#123; return m_error; &#125;
		char *GetFilename&#40;&#41; &#123; return m_FileName; &#125;

		/** Helpers */
		void SetName&#40;const char *strName&#41;;
		char *GetName&#40;&#41;;
	
	private&#58;
		SceUID StartModuleWithArgs&#40;char *filename, int modid, int argc, char * const argv&#91;&#93;&#41;;
		SceUID m_ModId;
		int  m_error;
		char *m_FileName;
		char *m_Name;
		bool m_IsStarted, m_IsLoaded;
	&#125;;
PRXLoader.cpp

Code: Select all

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <pspsdk.h>

#include "PRXLoader.h"

#define MAX_ARGS 2048

#define printf pspDebugScreenPrintf

CPRXLoader&#58;&#58;CPRXLoader&#40;&#41;
&#123;
	m_ModId = -1;
	m_FileName = NULL;
	m_error = 0;
	m_IsStarted = false;
	m_IsLoaded = false;
	m_Name = strdup&#40;"Off"&#41;;
&#125;

CPRXLoader&#58;&#58;~CPRXLoader&#40;&#41;
&#123;
	Unload&#40;&#41;;
	if &#40;m_FileName&#41;
	&#123;
		free&#40;m_FileName&#41;, m_FileName = NULL;
	&#125;
	if &#40;m_Name&#41;
	&#123;
		free&#40;m_Name&#41;, m_Name = NULL;
	&#125;

&#125;

void CPRXLoader&#58;&#58;SetName&#40;const char *strName&#41;
&#123;
	if &#40;m_Name&#41;
	&#123;
		free&#40;m_Name&#41;;
	&#125;
	m_Name = strdup&#40;strName&#41;;
&#125;

char *CPRXLoader&#58;&#58;GetName&#40;&#41;
&#123;
	if &#40;m_Name&#41;
	&#123;
		return m_Name;
	&#125;
	else
	&#123;
		return "Off";
	&#125;
&#125;


int CPRXLoader&#58;&#58;Load&#40;const char *filename&#41;
&#123;
	SceKernelLMOption option;
	SceUID mpid = PSP_MEMORY_PARTITION_USER;

	memset&#40;&option, 0, sizeof&#40;option&#41;&#41;;
	
	option.size = sizeof&#40;option&#41;;
	option.mpidtext = mpid;
	option.mpiddata = mpid;
	option.position = 0;
	option.access = 1;

	SceSize am = sceKernelTotalFreeMemSize&#40;&#41;;
	printf&#40; "CPRXLoader&#58;&#58;Load&#40;'%s'&#41; - Available memory before loading&#58; %dbytes &#40;%dKB or %dMB&#41;\n", filename, am, am/1024, am/1024/1024 &#41;;
	am = sceKernelMaxFreeMemSize&#40;&#41;;
	printf&#40; "CPRXLoader&#58;&#58;Load&#40;'%s'&#41; -  Max&#40;continguos&#41; memory before loading&#58; %dbytes &#40;%dKB or %dMB&#41;\n", filename, am, am/1024, am/1024/1024 &#41;;

	m_ModId = sceKernelLoadModule&#40;filename, 0, &option&#41;;
	
	printf&#40; "CPRXLoader&#58;&#58;Load&#40;'%s'&#41; - Module Id = %d\n", filename, m_ModId &#41;;
	sleep&#40;1&#41;;
	
	if &#40;m_ModId > 0&#41;
	&#123;
		if &#40;m_FileName&#41;
		&#123;
			free&#40;m_FileName&#41;, m_FileName = NULL;
		&#125;
		m_FileName = strdup&#40;filename&#41;;
		m_error = 0;
		m_IsLoaded = true;
	&#125;
	else
	&#123;
		m_error = m_ModId;
		m_IsLoaded = false;
	&#125;
	
	return m_ModId;
&#125;

int CPRXLoader&#58;&#58;Unload&#40;&#41;
&#123;
	int ret = 0;
	int status = 0;
	
	if &#40;IsLoaded&#40;&#41; == true&#41;
	&#123;
		printf&#40; "CPRXLoader&#58;&#58;Unload - Stopping Module %d\n", m_ModId &#41;;
		if &#40;IsStarted&#40;&#41; == true&#41;
		&#123;
			// Stop
			printf&#40; "CPRXLoader&#58;&#58;Unload - Module was started, so stopping first.\n" &#41;;
			ret = sceKernelStopModule&#40;m_ModId, 0, NULL, &status, NULL&#41;;
			m_IsStarted = false;
		&#125;
		
		printf&#40; "StopModule returned 0x%x\n", ret &#41;;
		
		// Unload
		///if&#40;ret >= 0&#41;
		&#123;
			printf&#40; "Unload&#40;&#41;&#58; Unloading Module\n" &#41;;
			ret = sceKernelUnloadModule&#40;m_ModId&#41;;
			printf&#40; "UnloadModule returned 0x%x\n" &#41;;
		&#125;
		
		sleep&#40;1&#41;;
	
		m_ModId = 0;
		m_IsLoaded = false;
	&#125;

	return 0;
&#125;

int CPRXLoader&#58;&#58;Start&#40;int argc, char *const argv&#91;&#93;&#41;
&#123;
	return StartModuleWithArgs&#40;m_FileName, m_ModId, argc, argv&#41;;
&#125;

SceUID CPRXLoader&#58;&#58;StartModuleWithArgs&#40;char *filename, int modid, int argc, char * const argv&#91;&#93;&#41;
&#123;
	int retVal = 0, mresult = 0;
	char args&#91;MAX_ARGS&#93;;
	int  argpos = 0;
	int  i = 0;
	
	memset&#40;args, 0, MAX_ARGS&#41;;
	strcpy&#40;args, filename&#41;;
	argpos += strlen&#40;args&#41; + 1;
	
	for&#40;i = 0; &#40;i < argc&#41; && &#40;argpos < MAX_ARGS&#41;; i++&#41;
	&#123;
		int len;
		snprintf&#40;&args&#91;argpos&#93;, MAX_ARGS-argpos, "%s", argv&#91;i&#93;&#41;;
		len = strlen&#40;&args&#91;argpos&#93;&#41;;
		argpos += len + 1;
	&#125;
	
	retVal = sceKernelStartModule&#40;modid, argpos, args, &mresult, NULL&#41;;
	
	if&#40;retVal < 0&#41;
	&#123;
		m_IsStarted = false;
		return retVal;
	&#125;
	
	m_IsStarted = true;
	return modid;
&#125;
Main.cpp

Code: Select all

#include <pspkernel.h>
#include <pspsdk.h>

#include <stdio.h>
#include <stdlib.h>

#include <SDL/SDL.h>

#include "PRXLoader.h"
#include "plugin.h"


PSP_MODULE_INFO&#40;"LOADER", 0x0, 1, 1&#41;;
/* Define the main thread's attribute value &#40;optional&#41; */
PSP_MAIN_THREAD_ATTR&#40;PSP_THREAD_ATTR_VFPU&#41;;

#define printf 		pspDebugScreenPrintf
#define usleep&#40;x&#41; 	sceKernelDelayThread&#40; x * 1000000 &#41;

Plugin *plugin;

/* Exit callback */
int exit_callback&#40;int arg1, int arg2, void *common&#41;
&#123;
	sceKernelExitGame&#40;&#41;;
	return 0;
&#125;

/* Callback thread */
int CallbackThread&#40;SceSize args, void *argp&#41;
&#123;
	int cbid;

	cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;
	sceKernelRegisterExitCallback&#40;cbid&#41;;
	sceKernelSleepThreadCB&#40;&#41;;

	return 0;
&#125;

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks&#40;void&#41;
&#123;
	int thid = 0;

	thid = sceKernelCreateThread&#40;"update_thread", CallbackThread,
				     0x11, 0xFA0, 0, 0&#41;;
	if&#40;thid >= 0&#41;
	&#123;
		sceKernelStartThread&#40;thid, 0, 0&#41;;
	&#125;

	return thid;
&#125;

int main&#40; int argc, char *argv&#91;&#93; &#41; 
&#123;
	CPRXLoader *loader;
	
	pspDebugScreenInit&#40;&#41;;
	SetupCallbacks&#40;&#41;;
	
	loader = new CPRXLoader;
	
	if&#40; loader->Load&#40; "ms0&#58;/PSP/GAME150/PRXTest/plugin.prx" &#41; <= 0 &#41; &#123;
		printf&#40; "Cannot load plugin prx!\n" &#41;;
		usleep&#40; 1 &#41;;
		goto out;
	&#125;
	
	if&#40; loader->IsLoaded&#40; &#41; == true &#41; &#123;
		printf&#40; "Load OK\n" &#41;;
		usleep&#40; 1 &#41;;
		loader->Start&#40; &#41;;
	&#125;
	
	if&#40; loader->IsStarted&#40; &#41; == true &#41; &#123;
		printf&#40; "Module Started\n" &#41;;
		plugin = get_plugin_info&#40;&#41;;
		printf&#40; "Description&#58; %s\n", plugin->description &#41;;
		plugin->init&#40;&#41;;
	&#125;
	
	sceKernelDelayThread&#40; 5 * 1000000 &#41;;
	
	loader->Unload&#40; &#41;;
out&#58;
	sceKernelDelayThread&#40; 0 &#41;;
	sceKernelExitGame&#40; &#41;;
	return 0;
&#125;
Makefile

Code: Select all

TARGET = PluginTest
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Plugin Test

EXPORTS_OBJS = PluginStub.o

OBJS = Main.o PRXLoader.o \
	   $&#40;EXPORTS_OBJS&#41;

CFLAGS = -O2 -Wall -g -DPSP 
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

LIBDIR =
LDFLAGS =

LIBS =	-lstdc++ \
		-lSDLmain -lSDL -lGL \
	    -lpspvfpu -L/usr/local/pspdev/psp/sdk/lib -lpspdebug -lpspgu \
	    -lpspctrl -lpspge -lpspdisplay -lpsphprm -lpspsdk -lpsprtc \
	    -lpspaudio -lc -lpspuser -lpsputility -lpspkernel -lpspnet_inet
		
all&#58; $&#40;EXTRA_TARGETS&#41;

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak
And this from the PRX

plugin.h

Code: Select all

typedef struct
&#123;	
	char *description;	/* The description of the plugin */
	void &#40;*init&#41; &#40;void&#41;;	/* Called when the plugin is loaded */
&#125;
Plugin;

/* The plugin exports this function */
extern "C" Plugin *get_plugin_info&#40;&#41;;
plugin.cpp

Code: Select all

* Default headers */
#include <pspkernel.h>
#include <stdio.h>
#include <unistd.h> 
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <stdarg.h>

#include <ctype.h>
#include <string>
using namespace std;

#include "plugin.h"

PSP_MODULE_INFO&#40;"PLUGIN", 0, 1, 1&#41;;
PSP_HEAP_SIZE_KB&#40; 0 &#41;;

/* Prototypes */
static void init&#40;void&#41;;
/* End Prototypes */

/** START of Plugin definitions setup */
Plugin table = 
&#123;
	/* Populated by Plugin */
	"Plugin Test",	/* The description of the plugin */
	init							/* Called when the plugin is loaded */
&#125;;
/** END of Plugin definitions setup */

/** Single Plugin Export */
Plugin *get_plugin_info&#40;&#41;
&#123;
	return &table;
&#125;

static void init&#40;void&#41;
&#123;	
	char *text;
	
	text = new char&#91;100&#93;;
&#125;

#ifdef __cplusplus
extern "C" &#123;
#endif

/** START Plugin Boilerplate -- shouldn't need to change **/
PSP_NO_CREATE_MAIN_THREAD&#40;&#41;;
int module_start&#40;SceSize argc, void* argp&#41;
&#123;
	return 0;
&#125;
int module_stop&#40;int args, void *argp&#41;
&#123;
	return 0;
&#125;
/** END Plugin Boilerplate -- shouldn't need to change **/
#ifdef __cplusplus
&#125;
#endif
Makefile.prx

Code: Select all

TARGET = plugin

OBJS = plugin.o

# Define to build this as a prx &#40;instead of a static elf&#41;
BUILD_PRX = 1
# Define the name of our custom exports &#40;minus the .exp extension&#41;
PRX_EXPORTS = PluginExports.exp
		 
CFLAGS = -G0 -mno-explicit-relocs -fno-strict-aliasing -O2 -g -Wall -DPSP
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

LDFLAGS = -mno-crt0 -nostartfiles

LIBS = -lstdc++

all&#58; exports $&#40;TARGET&#41;.prx

exports&#58; 
	psp-build-exports -s PluginExports.exp

PSPSDK = $&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak
And finally PluginExports.exp

Code: Select all

# Define the exports for Plugin
PSP_BEGIN_EXPORTS

	# These four lines are mandatory &#40;although you can add other functions like module_stop&#41;
	# syslib is a psynonym for the single mandatory export.
	PSP_EXPORT_START&#40;syslib, 0, 0x8000&#41;
		PSP_EXPORT_FUNC_HASH&#40;module_start&#41;
		PSP_EXPORT_VAR_HASH&#40;module_info&#41;
		PSP_EXPORT_FUNC_HASH&#40;module_stop&#41;
	PSP_EXPORT_END
	
	# Export our function
	PSP_EXPORT_START&#40;PluginStub, 0, 0x0001&#41;
		PSP_EXPORT_FUNC_HASH&#40;get_plugin_info&#41;
	PSP_EXPORT_END

	
PSP_END_EXPORTS
Sorry for all the files. Now the app works ok until this line:

Code: Select all

plugin->init&#40;&#41;;
in the Main.cpp then it just freezes. Doing some debug i have found that if I remove the line

Code: Select all

text = new char&#91;100&#93;;
from the init function in plugin.cpp the app works fine. I have changed the new operator with a malloc and it works too... so the problem is with the stdc++ library? I need it because i will use a lot of c++ stuff like classes.

I don't know a lot about prx so Maybe i'm missing something?
Hope someone can help. Thanks in advance.
jas0nuk
Posts: 137
Joined: Thu Apr 27, 2006 8:00 am

Post by jas0nuk »

You don't need a trillion lines of code just to load a PRX...

Code: Select all

#define printf pspDebugScreenPrintf

SceUID mod = sceKernelLoadModule&#40;"ms0&#58;/plugin.prx", 0, NULL&#41;;
if &#40;mod < 0&#41; printf&#40;"Error 0x%08X loading plugin.prx", mod&#41;;

mod = sceKernelStartModule&#40;mod, 0, NULL, 0, NULL&#41;;
if &#40;mod < 0&#41;  printf&#40;"Error 0x%08X starting plugin.prx", mod&#41;;
PiCkDaT
Posts: 69
Joined: Thu Oct 04, 2007 9:49 pm

Post by PiCkDaT »

what jas0nuk said.. you dont need that much code to load a PRX... and also if you have the toolchain, you most likely have the samples right? theres a PRX loader sample there too...
Enlighten me, Reveal my fate -- Follow - Breaking Benjamin
aeolusc
Posts: 18
Joined: Sat Oct 14, 2006 12:17 pm

Post by aeolusc »

I've found this problem before, resolved by disabling all plugins preloaded by CFW. Thought it is a memory allocation conflict between stdc++ memory handle and users' prx plugin
Post Reply