forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Problem with PRX, freezes psp!

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
theHobbit



Joined: 30 Sep 2006
Posts: 65

PostPosted: Thu Oct 11, 2007 2:25 pm    Post subject: Problem with PRX, freezes psp! Reply with quote

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:

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

   #define _PRXLOADER_
   
   class CPRXLoader
   {
   public:
      CPRXLoader();
      ~CPRXLoader();
      int Load(const char *filename);
      int Unload();
      int Start(int argc = 0, char * const argv[] = NULL);
      bool IsLoaded()  { return m_IsLoaded; }
      bool IsStarted() { return m_IsStarted; }
      int  GetError()  { return m_error; }
      char *GetFilename() { return m_FileName; }

      /** Helpers */
      void SetName(const char *strName);
      char *GetName();
   
   private:
      SceUID StartModuleWithArgs(char *filename, int modid, int argc, char * const argv[]);
      SceUID m_ModId;
      int  m_error;
      char *m_FileName;
      char *m_Name;
      bool m_IsStarted, m_IsLoaded;
   };


PRXLoader.cpp
Code:

#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::CPRXLoader()
{
   m_ModId = -1;
   m_FileName = NULL;
   m_error = 0;
   m_IsStarted = false;
   m_IsLoaded = false;
   m_Name = strdup("Off");
}

CPRXLoader::~CPRXLoader()
{
   Unload();
   if (m_FileName)
   {
      free(m_FileName), m_FileName = NULL;
   }
   if (m_Name)
   {
      free(m_Name), m_Name = NULL;
   }

}

void CPRXLoader::SetName(const char *strName)
{
   if (m_Name)
   {
      free(m_Name);
   }
   m_Name = strdup(strName);
}

char *CPRXLoader::GetName()
{
   if (m_Name)
   {
      return m_Name;
   }
   else
   {
      return "Off";
   }
}


int CPRXLoader::Load(const char *filename)
{
   SceKernelLMOption option;
   SceUID mpid = PSP_MEMORY_PARTITION_USER;

   memset(&option, 0, sizeof(option));
   
   option.size = sizeof(option);
   option.mpidtext = mpid;
   option.mpiddata = mpid;
   option.position = 0;
   option.access = 1;

   SceSize am = sceKernelTotalFreeMemSize();
   printf( "CPRXLoader::Load('%s') - Available memory before loading: %dbytes (%dKB or %dMB)\n", filename, am, am/1024, am/1024/1024 );
   am = sceKernelMaxFreeMemSize();
   printf( "CPRXLoader::Load('%s') -  Max(continguos) memory before loading: %dbytes (%dKB or %dMB)\n", filename, am, am/1024, am/1024/1024 );

   m_ModId = sceKernelLoadModule(filename, 0, &option);
   
   printf( "CPRXLoader::Load('%s') - Module Id = %d\n", filename, m_ModId );
   sleep(1);
   
   if (m_ModId > 0)
   {
      if (m_FileName)
      {
         free(m_FileName), m_FileName = NULL;
      }
      m_FileName = strdup(filename);
      m_error = 0;
      m_IsLoaded = true;
   }
   else
   {
      m_error = m_ModId;
      m_IsLoaded = false;
   }
   
   return m_ModId;
}

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

   return 0;
}

int CPRXLoader::Start(int argc, char *const argv[])
{
   return StartModuleWithArgs(m_FileName, m_ModId, argc, argv);
}

SceUID CPRXLoader::StartModuleWithArgs(char *filename, int modid, int argc, char * const argv[])
{
   int retVal = 0, mresult = 0;
   char args[MAX_ARGS];
   int  argpos = 0;
   int  i = 0;
   
   memset(args, 0, MAX_ARGS);
   strcpy(args, filename);
   argpos += strlen(args) + 1;
   
   for(i = 0; (i < argc) && (argpos < MAX_ARGS); i++)
   {
      int len;
      snprintf(&args[argpos], MAX_ARGS-argpos, "%s", argv[i]);
      len = strlen(&args[argpos]);
      argpos += len + 1;
   }
   
   retVal = sceKernelStartModule(modid, argpos, args, &mresult, NULL);
   
   if(retVal < 0)
   {
      m_IsStarted = false;
      return retVal;
   }
   
   m_IsStarted = true;
   return modid;
}


Main.cpp
Code:

#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("LOADER", 0x0, 1, 1);
/* Define the main thread's attribute value (optional) */
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_VFPU);

#define printf       pspDebugScreenPrintf
#define usleep(x)    sceKernelDelayThread( x * 1000000 )

Plugin *plugin;

/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
   sceKernelExitGame();
   return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
   int cbid;

   cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
   sceKernelRegisterExitCallback(cbid);
   sceKernelSleepThreadCB();

   return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
   int thid = 0;

   thid = sceKernelCreateThread("update_thread", CallbackThread,
                 0x11, 0xFA0, 0, 0);
   if(thid >= 0)
   {
      sceKernelStartThread(thid, 0, 0);
   }

   return thid;
}

int main( int argc, char *argv[] )
{
   CPRXLoader *loader;
   
   pspDebugScreenInit();
   SetupCallbacks();
   
   loader = new CPRXLoader;
   
   if( loader->Load( "ms0:/PSP/GAME150/PRXTest/plugin.prx" ) <= 0 ) {
      printf( "Cannot load plugin prx!\n" );
      usleep( 1 );
      goto out;
   }
   
   if( loader->IsLoaded( ) == true ) {
      printf( "Load OK\n" );
      usleep( 1 );
      loader->Start( );
   }
   
   if( loader->IsStarted( ) == true ) {
      printf( "Module Started\n" );
      plugin = get_plugin_info();
      printf( "Description: %s\n", plugin->description );
      plugin->init();
   }
   
   sceKernelDelayThread( 5 * 1000000 );
   
   loader->Unload( );
out:
   sceKernelDelayThread( 0 );
   sceKernelExitGame( );
   return 0;
}


Makefile
Code:

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

EXPORTS_OBJS = PluginStub.o

OBJS = Main.o PRXLoader.o \
      $(EXPORTS_OBJS)

CFLAGS = -O2 -Wall -g -DPSP
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

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: $(EXTRA_TARGETS)

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak


And this from the PRX

plugin.h
Code:

typedef struct
{   
   char *description;   /* The description of the plugin */
   void (*init) (void);   /* Called when the plugin is loaded */
}
Plugin;

/* The plugin exports this function */
extern "C" Plugin *get_plugin_info();


plugin.cpp
Code:

* 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("PLUGIN", 0, 1, 1);
PSP_HEAP_SIZE_KB( 0 );

/* Prototypes */
static void init(void);
/* End Prototypes */

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

/** Single Plugin Export */
Plugin *get_plugin_info()
{
   return &table;
}

static void init(void)
{   
   char *text;
   
   text = new char[100];
}

#ifdef __cplusplus
extern "C" {
#endif

/** START Plugin Boilerplate -- shouldn't need to change **/
PSP_NO_CREATE_MAIN_THREAD();
int module_start(SceSize argc, void* argp)
{
   return 0;
}
int module_stop(int args, void *argp)
{
   return 0;
}
/** END Plugin Boilerplate -- shouldn't need to change **/
#ifdef __cplusplus
}
#endif


Makefile.prx
Code:

TARGET = plugin

OBJS = plugin.o

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

LDFLAGS = -mno-crt0 -nostartfiles

LIBS = -lstdc++

all: exports $(TARGET).prx

exports:
   psp-build-exports -s PluginExports.exp

PSPSDK = $(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak


And finally PluginExports.exp
Code:

# Define the exports for Plugin
PSP_BEGIN_EXPORTS

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

   
PSP_END_EXPORTS


Sorry for all the files. Now the app works ok until this line:
Code:
plugin->init();
in the Main.cpp then it just freezes. Doing some debug i have found that if I remove the line
Code:
text = new char[100];
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.
Back to top
View user's profile Send private message
jas0nuk



Joined: 27 Apr 2006
Posts: 137

PostPosted: Fri Oct 12, 2007 2:09 am    Post subject: Reply with quote

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

Code:
#define printf pspDebugScreenPrintf

SceUID mod = sceKernelLoadModule("ms0:/plugin.prx", 0, NULL);
if (mod < 0) printf("Error 0x%08X loading plugin.prx", mod);

mod = sceKernelStartModule(mod, 0, NULL, 0, NULL);
if (mod < 0)  printf("Error 0x%08X starting plugin.prx", mod);
Back to top
View user's profile Send private message
PiCkDaT



Joined: 04 Oct 2007
Posts: 69

PostPosted: Fri Oct 12, 2007 3:07 am    Post subject: Reply with quote

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
Back to top
View user's profile Send private message AIM Address
aeolusc



Joined: 14 Oct 2006
Posts: 18

PostPosted: Fri Oct 12, 2007 7:42 pm    Post subject: Reply with quote

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
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group