Making Hugo Programs

Hugo programming discussion. http://www.generalcoffee.com/hugo
Hugo By Example: http://hugo.gerynarsabode.org/index.php?title=Main_Page
Roody Yogurt's Hugo Blog: http://notdeadhugo.blogspot.com

Moderators: AArdvark, Ice Cream Jonsey

ICJ

Post by ICJ » Mon Nov 24, 2014 9:31 am

Hm, didn't see your note till just now. I actually hopped on my Mac, did a make and tried to compile Cyberganked.

I get this:

➜ cyberganked2 git:(master) ✗ ./hc cyberganked.hug
[1] 41939 abort ./hc cyberganked.hug

Just putting this here for now.

bruce
Posts: 2547
Joined: Tue Jun 04, 2002 10:43 pm

Post by bruce » Wed Nov 26, 2014 5:20 pm

So how about making with the source?

I can compile Colossal Cave and start it and play to releasing the bird at the snake (all on my Mac) and it seems to be fine.

User avatar
Ice Cream Jonsey
Posts: 21628
Joined: Sat Apr 27, 2002 2:44 pm
Location: Colorado
Contact:

Post by Ice Cream Jonsey » Wed Nov 26, 2014 6:17 pm

Hmm. Bet it has something to do with the long file names in the WIP. Well, not long file names, but the subdirectories and filenames blew up the Unix version 'fore I fixed it.

Sent you an invitation to your f*s*f address. Through bitbucket. Thanks, man.
the dark and gritty...Ice Cream Jonsey!

bruce
Posts: 2547
Joined: Tue Jun 04, 2002 10:43 pm

Post by bruce » Wed Nov 26, 2014 7:13 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:

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
So then we go to hccomp.c:

Code: Select all

                        strcpy(buffer, word[1]);
                        strcat(buffer, word[2]);
                        strcat(buffer, word[3]);
                        word[1] = buffer;
                        words = 1;
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.

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
....which is....

Code: Select all

        if (strcmp(dir, "") && fname[0]=='/') strcpy(fname, fname+1);
man strcpy tells us:

Code: Select all

     The source and destination strings should not overlap, as the behavior is undefined.
Apparently gcc on Linux lets you get away with that.

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;
          }
        }
And now he also runs cyberganked.hex.

Moral of the story: string handling in C blows.

bruce
Posts: 2547
Joined: Tue Jun 04, 2002 10:43 pm

Post by bruce » Wed Nov 26, 2014 7:16 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.

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, "");

User avatar
Ice Cream Jonsey
Posts: 21628
Joined: Sat Apr 27, 2002 2:44 pm
Location: Colorado
Contact:

Post by Ice Cream Jonsey » Fri Nov 28, 2014 12:19 am

It's the bees knees.

^_____________^

I just wrote Kent on the mud to seeing about getting this patched officially. I will test it on my Mac when I go to work next.

Thanks, man. You have saved an entire race of people with this.
the dark and gritty...Ice Cream Jonsey!

Roody_Yogurt
Posts: 1993
Joined: Mon Apr 29, 2002 6:23 pm
Location: Milwaukee

Post by Roody_Yogurt » Sun Nov 30, 2014 9:55 am

Awesome, bruce!

User avatar
Ice Cream Jonsey
Posts: 21628
Joined: Sat Apr 27, 2002 2:44 pm
Location: Colorado
Contact:

Post by Ice Cream Jonsey » Wed Dec 24, 2014 10:06 am

Posting this link as the download locations are included:

http://www.joltcountry.com/phpBB2/viewtopic.php?t=9511
the dark and gritty...Ice Cream Jonsey!

Post Reply