PRX won't run from MS

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

Moderators: cheriff, TyRaNiD

Post Reply
Criptych
Posts: 64
Joined: Sat Sep 12, 2009 5:18 am

PRX won't run from MS

Post by Criptych »

The program runs fine in PSPLink from host0, but when I try to run it from the MS, it crashes:

Code: Select all

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: Select all

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: Select all

///// 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 ^= &#40;uint8_t&#41;&#40;*name++&#41;;
      &#125;
   &#125;

   return hash;
&#125;

void pl2PackageIndexInsert&#40;const char *filename&#41;
&#123;
   pl2Package *pkg = pl2PackageOpen&#40;filename&#41;;
   
   if &#40;!pkg&#41; return;

   int i;
   
   //pl2PackageFile *attr = pl2PackageGetFile&#40;pkg, "attribute"&#41;;
   //if &#40;!attr&#41; return;
   
   for &#40;i = 0; i < pkg->numEntries; ++i&#41;
   &#123;
      uint32_t hash = pl2PackageIndexHash&#40;pkg->entry&#91;i&#93;.name, 28&#41; % PACKAGE_INDEX_SIZE;
    
      uint32_t index = hash;
      
      do
      &#123;
         if &#40;strncmp&#40;pkg->entry&#91;i&#93;.name, pl2PackageIndex&#91;index&#93;.name, 28&#41; == 0&#41;
         &#123;
            // already in index, don't add it
            break;
         &#125;

         if &#40;!pl2PackageIndex&#91;index&#93;.package&#41;
         &#123;
#if PACKAGELOG
            printf&#40;"\t%s\n", pkg->entry&#91;i&#93;.name&#41;;
            //if &#40;pkglog&#41; fprintf&#40;pkglog, "\t%s\n", pkg->entry&#91;i&#93;.name&#41;;
#endif

            // empty slot, add to index
            pl2PackageIndex&#91;index&#93;.package = pkg;
            strlcpy&#40;pl2PackageIndex&#91;index&#93;.name, pkg->entry&#91;i&#93;.name, 28&#41;;
            break;
         &#125;

         ++hash_collisions;

         if &#40;&#40;index += 17&#41; >= PACKAGE_INDEX_SIZE&#41;
         &#123;
            index -= PACKAGE_INDEX_SIZE;
         &#125;
      &#125;
      while &#40;pl2PackageIndex&#91;hash&#93;.package && &#40;index != hash&#41;&#41;;
   &#125;

   // close file handle &#40;but don't free&#41;   
   pl2PackageClose&#40;pkg&#41;;
&#125;

///// pl2_psp.c
bool pl2FileIoDopen&#40;void **ph, const char *name&#41;
&#123;
   SceUID handle = sceIoDopen&#40;name&#41;;
   
   DEBUGPRINT&#40;"pl2FileIoDopen&#58; sceIoDopen&#40;\"%s\"&#41; == %p\n", name, handle&#41;;

   if &#40;handle >= 0&#41;
   &#123;
      *ph = &#40;void *&#41;handle;
      return true;
   &#125;

   return false;
&#125;

int pl2FileIoDread&#40;void *handle, char *name, size_t size, uint32_t flags&#41;
&#123;
   SceIoDirent fd;

   int res = sceIoDread&#40;&#40;SceUID&#41;handle, &fd&#41;;
   
   if &#40;res > 0&#41;
   &#123;
      if &#40;!name&#41;
      &#123;
         DEBUGPRINT&#40;"pl2FileIoDread&#58; name == NULL\n"&#41;;
         return 0;
      &#125;
      
      //DEBUGPRINT&#40;"%u %s\n", size, fd.d_name&#41;;
      strlcpy&#40;name, fd.d_name, size&#41;;
   &#125;
   else if &#40;res < 0&#41;
   &#123;
      DEBUGPRINT&#40;"pl2FileIoDread&#58; sceIoDread&#40;%p, %p&#41; == %d\n", handle, &fd, res&#41;;
   &#125;

   return res;
&#125;

void pl2FileIoDclose&#40;void *handle&#41;
&#123;
   sceIoDclose&#40;&#40;SceUID&#41;handle&#41;;
&#125;
I'm not ruling out stupid mistakes yet, but any help is appreciated.
"You hungry? I haven't eaten since later this afternoon."
SilverSpring
Posts: 110
Joined: Tue Feb 27, 2007 9:43 pm
Contact:

Post by SilverSpring »

Maybe buffer overflow.

In pl2PackageIndexCreate(), you have filename[64] yet you do snprintf(filename, 256, "./add-ons/%s", entry);
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

You need to zero out the SceIoDirent before calling sceIoDread, otherwise it will try to dereference .d_private and die.
sauron_le_noir
Posts: 203
Joined: Sat Jul 05, 2008 8:03 am

Post by sauron_le_noir »

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.
Criptych
Posts: 64
Joined: Sat Sep 12, 2009 5:18 am

Post by Criptych »

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?
"You hungry? I haven't eaten since later this afternoon."
Post Reply