Making Hugo Programs
Moderators: Ice Cream Jonsey, joltcountry
- Ice Cream Jonsey
- Posts: 30184
- Joined: Sat Apr 27, 2002 2:44 pm
- Location: Colorado
- Contact:
-
- Posts: 2544
- Joined: Tue Jun 04, 2002 10:43 pm
Well, a little dicking around (Mavericks doesn't include gdb anymore, so I needed to switch compiler to clang and then run under lldb) shows where it's crashing:
So then we go to hccomp.c:
It's that first strcat.
buffer is defined as extern char[] in hcheader.h.
There is no definition of buffer in hccomp.c.
So I guess it's getting implicitly initialized to some fixed size by strcpy? And then you're immediately appending to it, and the compiler is getting nervous?
So we simply declare buffer as char[256] at the top of CompilerMem.
Compilation now succeeds. And running the game in Hugor looks like it works. But still, let's see what else we find in the CLI tools.
Now he fails in the same way.
....which is....
man strcpy tells us:
Apparently gcc on Linux lets you get away with that.
So let's replace that with a cheesy strcpy implementation instead.
And now he also runs cyberganked.hex.
Moral of the story: string handling in C blows.
Code: Select all
(lldb) bt
* thread #1: tid = 0x7e19f, 0x00007fff9034e286 libsystem_kernel.dylib`__pthread_kill + 10, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
* frame #0: 0x00007fff9034e286 libsystem_kernel.dylib`__pthread_kill + 10
frame #1: 0x00007fff9247542f libsystem_pthread.dylib`pthread_kill + 90
frame #2: 0x00007fff8cb65b53 libsystem_c.dylib`abort + 129
frame #3: 0x00007fff8cb65cca libsystem_c.dylib`abort_report_np + 181
frame #4: 0x00007fff8cb8bdb0 libsystem_c.dylib`__chk_fail + 48
frame #5: 0x00007fff8cb8bdc0 libsystem_c.dylib`__chk_fail_overlap + 16
frame #6: 0x00007fff8cb8bde2 libsystem_c.dylib`__chk_overlap + 34
frame #7: 0x00007fff8cb8c117 libsystem_c.dylib`__strcat_chk + 81
frame #8: 0x0000000100016cf9 hc`CompilerMem + 217 at hccomp.c:332
frame #9: 0x0000000100017766 hc`Pass1 + 422 at hcpass.c:91
frame #10: 0x0000000100000dbb hc`main(argc=2, argv=0x00007fff5fbffb50) + 171 at hc.c:64
frame #11: 0x00007fff8ca9f5c9 libdyld.dylib`start + 1
Code: Select all
strcpy(buffer, word[1]);
strcat(buffer, word[2]);
strcat(buffer, word[3]);
word[1] = buffer;
words = 1;
buffer is defined as extern char[] in hcheader.h.
There is no definition of buffer in hccomp.c.
So I guess it's getting implicitly initialized to some fixed size by strcpy? And then you're immediately appending to it, and the compiler is getting nervous?
So we simply declare buffer as char[256] at the top of CompilerMem.
Compilation now succeeds. And running the game in Hugor looks like it works. But still, let's see what else we find in the CLI tools.
Now he fails in the same way.
Code: Select all
frame #7: 0x00007fff8cb8bfbf libsystem_c.dylib`__strcpy_chk + 64
frame #8: 0x000000010001a8e1 he`hugo_splitpath(path=0x00007fff5fbffc48, drive=0x00007fff5fbff9f0, dir=0x00007fff5fbff8f0, fname=0x00007fff5fbff7f0, ext=0x00007fff5fbff6f0) + 849 at hegcc.c:165
Code: Select all
if (strcmp(dir, "") && fname[0]=='/') strcpy(fname, fname+1);
Code: Select all
The source and destination strings should not overlap, as the behavior is undefined.
So let's replace that with a cheesy strcpy implementation instead.
Code: Select all
if (strcmp(dir, "") && fname[0]=='/') {
int i = 0;
while(1) {
fname[i]=fname[++i];
if (fname[i] == '\0') break;
}
}
Moral of the story: string handling in C blows.
-
- Posts: 2544
- Joined: Tue Jun 04, 2002 10:43 pm
Does Kent read this forum?
Here are the patches. No idea if 256 bytes is really right for the buffer, or if we're really guaranteed that fname is null-terminated, but hey. You get what you pay for.
Here are the patches. No idea if 256 bytes is really right for the buffer, or if we're really guaranteed that fname is null-terminated, but hey. You get what you pay for.
Code: Select all
--- hegcc.orig 2014-11-26 20:03:42.000000000 -0600
+++ hegcc.c 2014-11-26 20:11:15.000000000 -0600
@@ -162,7 +162,13 @@
}
else strcpy(fname,file);
- if (strcmp(dir, "") && fname[0]=='/') strcpy(fname, fname+1);
+ if (strcmp(dir, "") && fname[0]=='/') {
+ int i = 0;
+ while(1) {
+ fname[i]=fname[++i];
+ if (fname[i] == '\0') break;
+ }
+ }
}
Code: Select all
--- hccomp.c.orig 2014-11-26 19:42:06.000000000 -0600
+++ hccomp.c 2014-11-26 19:53:39.000000000 -0600
@@ -317,6 +317,7 @@
void CompilerMem(void)
{
char e[64];
+ char buffer[256];
strcpy(e, "");
- Ice Cream Jonsey
- Posts: 30184
- Joined: Sat Apr 27, 2002 2:44 pm
- Location: Colorado
- Contact:
- Ice Cream Jonsey
- Posts: 30184
- Joined: Sat Apr 27, 2002 2:44 pm
- Location: Colorado
- Contact:
Posting this link as the download locations are included:
http://www.joltcountry.com/phpBB2/viewtopic.php?t=9511
http://www.joltcountry.com/phpBB2/viewtopic.php?t=9511
the dark and gritty...Ice Cream Jonsey!