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 

PRX won't run from MS

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



Joined: 12 Sep 2009
Posts: 79

PostPosted: Sun Jan 31, 2010 5:23 am    Post subject: PRX won't run from MS Reply with quote

The program runs fine in PSPLink from host0, but when I try to run it from the MS, it crashes:
Code:
Exception - Bus error (data)
Thread ID - 0x044CAE05
Th Name   - user_main
Module ID - 0x002A3C43
Mod Name  - sceSystemMemoryManager
EPC       - 0x8800DFDC
Cause     - 0x1000001C
BadVAddr  - 0x002A5400
Status    - 0x60088603
zr:0x00000000 at:0x40000000 v0:0x00000000 v1:0x00000000
a0:0x00000001 a1:0x8818D0ED a2:0x0000000D a3:0x00000001
t0:0x0000002E t1:0x00000000 t2:0x00000001 t3:0x00000000
t4:0x00003C3B t5:0x88014D90 t6:0x88014798 t7:0x00040000
s0:0x00000001 s1:0x8818CCD8 s2:0x8818C4D0 s3:0x8817B024
s4:0x8818D4E0 s5:0x09FBFBE0 s6:0x8818D904 s7:0x8818CEEC
t8:0x00000001 t9:0x00000001 k0:0x09FBFF00 k1:0x00000013
gp:0x088C17F0 sp:0x882F60D0 fp:0x882265A0 ra:0x8816E938
0x8800DFDC: 0xA0E80000 '....' - sb         $t0, 0($a3)


GDB wasn't very helpful, either:
Code:
Program received signal SIGBUS, Bus error.
0xffffffff8800dfdc in ?? ()

All I can tell from tracing through is that it occurs sometime after a call to sceIoDread. Also relevant is the fact that it doesn't occur in the debug build, but there's no significant change to that part of the code in the release build (DEBUGPRINT(x...) is defined as printf(x) for debug, empty for release; PACKAGELOG is defined as 1 in both configurations). Here's the affected code for reference:
Code:
///// pl2.c

extern bool pl2FileIoDopen(void **handle, const char *path);
extern int pl2FileIoDread(void *handle, char *name, size_t size, uint32_t flags);
extern void pl2FileIoDclose(void *handle);

typedef struct
{
   char name[28];
   pl2Package *package;
}
pl2PackageIndexEntry;

static pl2PackageIndexEntry pl2PackageIndex[PACKAGE_INDEX_SIZE];
static size_t hash_collisions = 0;

#if PACKAGELOG
//static FILE *pkglog = 0;
#endif

void pl2PackageIndexCreate()
{
   memset(pl2PackageIndex, 0, sizeof(pl2PackageIndex));

#if PACKAGELOG
   //if (!pkglog) pkglog = fopen("package.log", "wb");
   //if (!pkglog) { PL2_SET_ERROR(PL2_ERR_FILEIO); return; }
#endif

   void *dir;
   if (!pl2FileIoDopen(&dir, "./add-ons"))
   {
#if PACKAGELOG
      printf("Error opening 'add-ons' directory\n");
      //fprintf(pkglog, "Error opening 'add-ons' directory\n");
      //fclose(pkglog);
#endif

      PL2_SET_ERROR(PL2_ERR_NOTFOUND);
      return;
   }

   char entry[64] = { 0 }, filename[64] = { 0 };

#if PACKAGELOG
   printf("Add-ons found:\n");
   //fprintf(pkglog, "Add-ons found:\n");
#endif

   size_t count = 0;

   while (pl2FileIoDread(dir, entry, sizeof(entry), 0) > 0)
   {
      int l = strlen(entry);

      if (0 == strcasecmp(entry + l - 4, ".pl2"))
      {
#if PACKAGELOG
         printf("\n%s\n", entry);
         //fprintf(pkglog, "\n%s\n", entry);
#endif

         snprintf(filename, 256, "./add-ons/%s", entry);
         pl2PackageIndexInsert(filename);
         ++count;
      }
   }

#if PACKAGELOG
   if (!count)
   {
      printf("\nNone.\n");
      //fprintf(pkglog, "\nNone.\n");
   }
   if (hash_collisions)
   {
      printf("%u hash collisions while creating index.\n", hash_collisions);
      //fprintf(pkglog, "%u hash collisions while creating index.\n", hash_collisions);
   }
   //fclose(pkglog);
   //pkglog = 0;
#endif

   pl2FileIoDclose(dir);
}

static uint32_t pl2PackageIndexHash(const char *name, size_t len)
{
   uint32_t hash = 0xABad5eed;
   
   if (name)
   {
      while (*name && len--)
      {
         hash <<= 4;
         hash ^= (uint8_t)(*name++);
      }
   }

   return hash;
}

void pl2PackageIndexInsert(const char *filename)
{
   pl2Package *pkg = pl2PackageOpen(filename);
   
   if (!pkg) return;

   int i;
   
   //pl2PackageFile *attr = pl2PackageGetFile(pkg, "attribute");
   //if (!attr) return;
   
   for (i = 0; i < pkg->numEntries; ++i)
   {
      uint32_t hash = pl2PackageIndexHash(pkg->entry[i].name, 28) % PACKAGE_INDEX_SIZE;
   
      uint32_t index = hash;
     
      do
      {
         if (strncmp(pkg->entry[i].name, pl2PackageIndex[index].name, 28) == 0)
         {
            // already in index, don't add it
            break;
         }

         if (!pl2PackageIndex[index].package)
         {
#if PACKAGELOG
            printf("\t%s\n", pkg->entry[i].name);
            //if (pkglog) fprintf(pkglog, "\t%s\n", pkg->entry[i].name);
#endif

            // empty slot, add to index
            pl2PackageIndex[index].package = pkg;
            strlcpy(pl2PackageIndex[index].name, pkg->entry[i].name, 28);
            break;
         }

         ++hash_collisions;

         if ((index += 17) >= PACKAGE_INDEX_SIZE)
         {
            index -= PACKAGE_INDEX_SIZE;
         }
      }
      while (pl2PackageIndex[hash].package && (index != hash));
   }

   // close file handle (but don't free)   
   pl2PackageClose(pkg);
}

///// pl2_psp.c
bool pl2FileIoDopen(void **ph, const char *name)
{
   SceUID handle = sceIoDopen(name);
   
   DEBUGPRINT("pl2FileIoDopen: sceIoDopen(\"%s\") == %p\n", name, handle);

   if (handle >= 0)
   {
      *ph = (void *)handle;
      return true;
   }

   return false;
}

int pl2FileIoDread(void *handle, char *name, size_t size, uint32_t flags)
{
   SceIoDirent fd;

   int res = sceIoDread((SceUID)handle, &fd);
   
   if (res > 0)
   {
      if (!name)
      {
         DEBUGPRINT("pl2FileIoDread: name == NULL\n");
         return 0;
      }
     
      //DEBUGPRINT("%u %s\n", size, fd.d_name);
      strlcpy(name, fd.d_name, size);
   }
   else if (res < 0)
   {
      DEBUGPRINT("pl2FileIoDread: sceIoDread(%p, %p) == %d\n", handle, &fd, res);
   }

   return res;
}

void pl2FileIoDclose(void *handle)
{
   sceIoDclose((SceUID)handle);
}


I'm not ruling out stupid mistakes yet, but any help is appreciated.
_________________
PSP-2000 // CFW: 5.50 GEN-D2 ...and not upgrading until OFW supports homebrew!
(But I did downgrade to 1.50 with TimeMachine...)
"I want you to tell me how the machine makes you feel."
Back to top
View user's profile Send private message
SilverSpring



Joined: 27 Feb 2007
Posts: 115

PostPosted: Sun Jan 31, 2010 5:41 am    Post subject: Reply with quote

Maybe buffer overflow.

In pl2PackageIndexCreate(), you have filename[64] yet you do snprintf(filename, 256, "./add-ons/%s", entry);
_________________
PSP PRX LibDocs
Back to top
View user's profile Send private message Visit poster's website
jimparis



Joined: 10 Jun 2005
Posts: 1179
Location: Boston

PostPosted: Sun Jan 31, 2010 7:24 am    Post subject: Reply with quote

You need to zero out the SceIoDirent before calling sceIoDread, otherwise it will try to dereference .d_private and die.
Back to top
View user's profile Send private message
sauron_le_noir



Joined: 05 Jul 2008
Posts: 229

PostPosted: Sun Jan 31, 2010 8:55 am    Post subject: Reply with quote

under debug buffer are memset to 0 and not when you run your program without debug, so if you forgot to init some variable the program doesn't crash under debug
but well without it.
Back to top
View user's profile Send private message Send e-mail MSN Messenger
Criptych



Joined: 12 Sep 2009
Posts: 79

PostPosted: Sun Jan 31, 2010 8:55 am    Post subject: Reply with quote

jimparis wrote:
You need to zero out the SceIoDirent before calling sceIoDread, otherwise it will try to dereference .d_private and die.

To quote the Great Master, "D'oh!" :P Yes, that fixed it, thanks a lot.

How come something this important isn't in the docs?

SilverSpring wrote:
Maybe buffer overflow.

In pl2PackageIndexCreate(), you have filename[64] yet you do snprintf(filename, 256, "./add-ons/%s", entry);

Thanks for pointing that out - it didn't cause the problem this time, but might have later on.

sauron_le_noir wrote:
under debug buffer are memset to 0 and not when you run your program without debug, so if you forgot to init some variable the program doesn't crash under debug
but well without it.

That explains the different outcomes, but I wonder why it worked from host0 regardless; maybe the usbhost driver ignores d_private?
_________________
PSP-2000 // CFW: 5.50 GEN-D2 ...and not upgrading until OFW supports homebrew!
(But I did downgrade to 1.50 with TimeMachine...)
"I want you to tell me how the machine makes you feel."
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