Mar. 18th, 2013

tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)

I got my week off to a good start by restoring a "new" laptop from my TimeMachine backup, for the second time in about ten days. (After last week's 193 million memory errors.)

After the restore (which took about an hour, fortuitously coinciding with the weekly all-hands meeting) I started my three Rust workspaces building, and after some strategic sledgehammer (removing-the-build-directory) applications, that actually succeeded. So I went back to alternating between work on rustpkg and the typechecker refactor, as build times permitted.

I actually made some progress on rustpkg: last week I'd started trying to port an example of a custom Makefile into a package script instead. The example package I'm using, rust-sdl, currently has a Makefile with this rule (which only fires when building on Macs):

$(SDLXMAIN): $(SDL_PREFIX)/libSDLmain.a
        $(CP) $< $@
        $(AR) -x $@ SDLMain.o || $(RM) -f $@
        $(LD) -r SDLMain.o -o SDLXMain.o -alias _main _SDLX_main \
             -unexported_symbol main || $(RM) -f $@
        $(MV) SDLXMain.o SDLMain.o || $(RM) -f $@
        $(CHMOD) u+w $@ || $(RM) -f $@
        $(AR) -r $@ SDLMain.o || $(RM) -f $@
It's not for me to ask why; anyway, being fairly simple, this made a good example for me. I transliterated it into Rust like so:
const SDL_PREFIX : &static/str = "/usr/local/lib";

#[pkg_do(post_build)]
fn post_build() {
 // todo: delete new_sdl_lib_name if any commands fail
    let existing_sdl_lib_name = path(SDL_PREFIX).push("libSDLmain.a");
    let new_sdl_lib_name = path(SDL_PREFIX).push("libSDLXmain.a");
    let sdl_obj_file = ~"SDLMain.o";
    let sdlx_obj_file = ~"SDLXmain.o";
    copy_file(existing_sdl_lib_name, new_sdl_lib_name);
    archive_file(Extract, new_sdl_lib_name, sdl_obj_file);
    load_file(sdl_obj_file, sdlx_obj_file, ~[(~"_main", ~"_SDLX_main")],
              ~[(~"_main")]);
    move_file(sdlx_obj_file, sdl_obj_file);
    change_file_permissions((User, Writable), new_sdl_lib_name);
    archive_file(Extract, sdl_obj_file);
}
This is still sketchy and I haven't actually implemented most of the functions above yet. But the basic idea for what we're trying to do in rustpkg is that as much functionality as possible should be in the Rust build system; you shouldn't need to write a Makefile even to do something fancy.

So I spent that part of today trying to make this work. It doesn't yet, but I did get up to the point where rustpkg fails with a resolve error -- when calling out to compile the code in the package script -- because the functions I didn't implement yet aren't defined. Most of that time was spent defining a new version of rustpkg's PackageScript structure that has a PkgId field instead of a name field and a version field. PkgIds just bundle together the name and version of the package, both of which now will be inferred from the directory name (or version control info if present) if not declared. (The existing version of rustpkg that's up on github requires you to declare your package's name and version explicitly.)

The typechecker situation is sadder; I fixed my bad merges and ran tests, only to find that one of the run-fail tests was failing with a nondeterministic error:

  • Assertion failed: ((Ty->isIntegerTy() || Ty->isPointerTy()) && "Invalid cast"), \
        function CreatePointerCast, \
        file /Users/tchevalier/rust3/src/llvm/lib/VMCore/Instructions.cpp, \
         line 2385.
    
  • error: internal compiler error: Asked to compute contents of fictitious type
  • rustc(29409,0x107cca000) malloc: *** error for object 0x7fdd9ba19f80: pointer \
        being freed was not allocated
    *** set a breakpoint in malloc_error_break to debug
    
  • Assertion failed: (box->td != NULL), function free, \
       file /Users/tchevalier/rust3/src/rt/boxed_region.cpp, line 75.

These are all different error messages that I got on different runs of the same test. Because this behavior looked so similar to what was happening on the other, broken laptop (though with a different test), I thought maybe this one was borked too. What are the chances of that? It's like in the joke that goes "I always bring a bomb with me when I fly, because what are the chances of there being two bombs on the airplane?" Running valgrind, though, assuaged that fear, since it actually worked (and reported a metric crap-ton of invalid reads), as opposed to declaring its inability to execute rustc (like on the broken laptop). The errors suggest some sort of memory corruption having to do with types, which isn't totally surprising since rustc represents types in a totally unsafe way, and it would be easy to get something wrong. It's still puzzling me that I can get so many tests to work with only one failing if I introduced a bug like that, though. Usually, these kinds of failures are catastrophic.

Anyway, progress, in that I closed the day with a laptop that isn't obviously broken, unlike last Friday...

Profile

tim: Tim with short hair, smiling, wearing a black jacket over a white T-shirt (Default)
Tim Chevalier

November 2021

S M T W T F S
 123456
78 910111213
14151617181920
21222324252627
282930    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags