 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
Criptych
Joined: 12 Sep 2009 Posts: 79
|
Posted: Sun Jan 31, 2010 5:23 am Post subject: PRX won't run from MS |
|
|
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 |
|
 |
SilverSpring
Joined: 27 Feb 2007 Posts: 115
|
Posted: Sun Jan 31, 2010 5:41 am Post subject: |
|
|
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 |
|
 |
jimparis
Joined: 10 Jun 2005 Posts: 1179 Location: Boston
|
Posted: Sun Jan 31, 2010 7:24 am Post subject: |
|
|
| You need to zero out the SceIoDirent before calling sceIoDread, otherwise it will try to dereference .d_private and die. |
|
| Back to top |
|
 |
sauron_le_noir
Joined: 05 Jul 2008 Posts: 229
|
Posted: Sun Jan 31, 2010 8:55 am Post subject: |
|
|
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 |
|
 |
Criptych
Joined: 12 Sep 2009 Posts: 79
|
Posted: Sun Jan 31, 2010 8:55 am Post subject: |
|
|
| 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 |
|
 |
|
|
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
|