racket / raco-cross

Other
7 stars 6 forks source link

fasl-read: incompatible fasl-object machine-type 'ta6nt found in #<binary input port bytevector> #5

Closed sschwarzer closed 1 year ago

sschwarzer commented 3 years ago

The error message is the same as for https://github.com/racket/raco-cross/issues/3 and https://github.com/mflatt/raco-cross/issues/3 , but this issue seems to be different.

The host system is Fedora Linux 34 with Racket 8.2 cs and the newest version of raco cross. (I even checked in the source code, if the change https://github.com/racket/raco-cross/commit/79de8356d20ec79b4fed58c32f4ab45dbfbf485c is present.) Also, the Racket installation is set to use installation scope anyway.

I tried to narrow down the problem, but I still need my project directory from https://git.sr.ht/~sschwarzer/sudoku-solver . On the other hand, at least you don't need the makefile. :-)

Now, if I clone my repo, remove ~/.local/share/racket/raco-cross/8.2 and run this script,

$ cat reproduce_issue.sh 
#! /bin/sh

# Compiled files cause trouble if they were compiled for a different target/VM.
find . -type d -name compiled | xargs rm -rf
# Ignore uninstalled package.
raco cross --target x86_64-win32 pkg remove sudoku-solver || true
# Implicitly install dependencies.
raco cross --target x86_64-win32 pkg install --deps search-auto
raco cross --target x86_64-win32 pkg remove sudoku-solver
# If the `compiled` directories are deleted here, the `raco cross exe`
# invocation fails with
# fasl-read: incompatible fasl-object machine-type 'ta6nt found in #<binary input port bytevector>
#
# If the `compiled` directories are left alone _here_, the
# `raco cross exe` invocation generates the binary, but the _next_
# run of `reproduce_issue.sh` fails with the `fasl-read` exception.
#
# find . -type d -name compiled | xargs rm -rf
raco cross --target x86_64-win32 exe --orig-exe --embed-dlls \
    -o sudoku-solver.exe games/sudoku-solver.rkt

The Windows binary is created as expected. However, if the line find . -type d -name compiled | xargs rm -rf is commented out, the raco cross exe invocation after that line fails with

fasl-read: incompatible fasl-object machine-type 'ta6nt found in #<binary input port bytevector>
  context...:
   body of syntax-literals
   /home/schwa/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/collects/compiler/embed.rkt:445:0: get-code
   [repeats 1 more time]
   /home/schwa/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/collects/racket/private/map.rkt:267:2: gen-for-each
   /home/schwa/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/collects/compiler/embed.rkt:1178:0: do-write-module-bundle
   /home/schwa/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/collects/compiler/embed.rkt:1658:15: write-module
   /home/schwa/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/collects/compiler/embed.rkt:1562:6
   /home/schwa/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/share/pkgs/compiler-lib/compiler/commands/exe.rkt:100:0
   body of "/home/schwa/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/share/pkgs/compiler-lib/compiler/commands/exe.rkt"
   /home/schwa/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/collects/raco/raco.rkt:41:0
   body of "/home/schwa/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/collects/raco/raco.rkt"
   body of "/home/schwa/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/collects/raco/main.rkt"
raco cross: command failed

If the find ... command is not commented out, the next run of reproduce_issue.sh fails with the same stacktrace. The only workaround I've found is to remove ~/.local/share/racket/raco-cross/8.2 and then re-run the script (or rather the equivalent section from the Makefile).

I've tried for hours to find out what happens here, without success. It's really strange (to me) why the files under the compiled directories should be needed even after the package is removed. After all, I can run a native raco exe -o sudoku-solver-linux games/sudoku-solver.rkt (when the dependencies are installed) without needing the files under compiled.

Ideally, I'd be interested in an explanation what's going on, but I'd also be relatively content with a suggestion of a workaround that doesn't require to remove and bootstrap the target installation for each compilation. Of course, if this can be fixed in raco cross or possibly Racket, this would be even better. By the way, I'm rather sure the Makefile used to work previously, so I wonder if there's possibly a change from Racket 8.1 to 8.2 that triggers the problem.

sschwarzer commented 3 years ago

By the way, when the fasl-read error is raised, would it be possible to output which file (path) led to the bytevector? I guess this might help with debugging such problems.

mflatt commented 3 years ago

It looks like this is a problem with raco exe in cross-compile mode. Unfortunately, that means it can't be fixed in just raco cross, but has to be fixed in the distributon.

I've pushed a repair for the next snapshot. Meanwhile, the best workaround is probably to use raco make before raco exe.

sschwarzer commented 3 years ago

@mflatt , thanks for the feedback.

Meanwhile, the best workaround is probably to use raco make before raco exe.

I changed the script to

#! /bin/sh

# Compiled files cause trouble if they were compiled for a different target/VM.
find . -type d -name compiled | xargs rm -rf
# Ignore uninstalled package.
raco cross --target x86_64-win32 pkg remove sudoku-solver || true
# Implicitly install dependencies.
raco cross --target x86_64-win32 pkg install --deps search-auto
raco cross --target x86_64-win32 pkg remove sudoku-solver
#
raco cross --target x86_64-win32 make games/sudoku-solver.rkt
raco cross --target x86_64-win32 exe --orig-exe --embed-dlls \
    -o sudoku-solver.exe games/sudoku-solver.rkt
find . -type d -name compiled | xargs rm -rf

Is that what you meant? I still get the fasl-read exception on the second run of the script.

I plan to try the Racket version from master with your fix later today.

mflatt commented 3 years ago

That's what I meant. I now see the problem with that workaround, though. Removing compiled does not remove the host shadow in <workarea>/x86_64-win32-cs/build/zo/, and raco make doesn't detect the half-built state. Probably the right additional repair is to improve raco make in cross-compile mode.

Meanwhile, a further workaround is to remove shadow compiled directories within <workarea>/x86_64-win32-cs/build/zo/. Within zo/, the path is based to a shadow compiled directory is based on the absolute path to the normal compiled directory.

sschwarzer commented 3 years ago

I still get the fasl-read error on the second run of reproduce_issue.sh.

Meanwhile, a further workaround is to remove shadow compiled directories within /x86_64-win32-cs/build/zo/.

By "workarea", I assume you mean the directory where raco-cross puts its files, i. e. ~/.local/share/racket/raco-cross/8.2 on my system? (I just see that raco cross outputs a "Workspace" directory for each run; you probably mean this, right?)

I don't know what a shadow compiled directory is, but I assume you mean that any compiled directory under <workarea>/x86_64-win32-cs/build/zo/ is a shadow compiled directory?

Within zo/, the path is based to a shadow compiled directory is based on the absolute path to the normal compiled directory.

I don't understand this sentence. Is the grammar as you intended?


Regarding the workaround of removing compiled directories in the workarea: After running reproduce_issue.sh, I ran

find ~/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/build/zo -name compiled -type d | xargs rm -rf

When I run reproduce_issue.sh after this, every run of raco cross fails with the fasl-read error, not just the raco exe invocation. I notice the stacktraces are much shorter though:

>> Cross configuration
 Target:    x86_64-win32
 Host:      x86_64-linux
 Version:   8.2
 VM:        cs
 Workspace: /home/schwa/.local/share/racket/raco-cross/8.2
fasl-read: incompatible fasl-object machine-type 'ta6nt found in #<binary input port bytevector>
  context...:
   body of data
   body of "/home/schwa/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/collects/raco/main.rkt"
raco cross: command failed

As far as I can tell, I get exactly this same output four times.

mflatt commented 3 years ago

Unfortunately, since the problem is in the distribution, then it won't help to use a newer Racket to run raco cross. Instead, you'd need to use a snapshot build (https://docs.racket-lang.org/raco-cross/index.html#%28part._snapshots%29) in place of v8.2. Doing things with compiled and raco exe ... make is an alternative to using a snapshot build.

Meanwhile, ~/.local/share/racket/raco-cross/8.2/x86_64-win32-cs/build/zo is not quite the directory I was trying to refer to. By removing all compiled directories within the zo directory, it's as if raco setup has never been run for the cross installation, and that will indeed make raco cross ... exe fail even more with v8.2. You can use raco cross --target x86_64-win32 setup to get the cross installation back into reasonable shape. (Unless I'm forgetting yet another thing.)

Then:

Maybe the better strategy is to use a snapshot instead of v8.2, and then you don't need to adjust zo or compiled directories to work around problems in the distribution.

Or, here's one more workaround — probably the easiest, but also the slowest: Remove the cross installation with raco cross --target x86_64-win32 --remove to start fresh every time you want to rebuild By starting with a fresh cross installation, you avoid any mismatched state from old/removed compiled directories.

sschwarzer commented 3 years ago

Unfortunately, since the problem is in the distribution, then it won't help to use a newer Racket to run raco cross.

That was surprising. I hadn't thought it would make a difference if I recompiled the Racket binaries.

Instead, you'd need to use a snapshot build (https://docs.racket-lang.org/raco-cross/index.html#%28part._snapshots%29) in place of v8.2.

From the link I conclude that with "snapshot" (aka "distribution"?) you weren't referring to a new version of the host system (as I thought), but different snapshots to be installed by raco cross. Is this correct now? :-) If yes, this would mean, if I'm not mistaken, that the cross compilation problem with raco exe will only be "properly" fixed when Racket 8.3 comes out because then raco cross will by default use the Racket 8.3 snapshots which contain the fix.

Or, here's one more workaround — probably the easiest, but also the slowest: Remove the cross installation with raco cross --target x86_64-win32 --remove to start fresh every time you want to rebuild

I guess I'm going with this for now instead of fiddling with the right compiled directories or snapshots. :-)

My workaround so far was to remove the whole workspace. Selectively removing the target with --remove seems to work indeed, from what I have just tried, so this saves at least the time for creating the other directories in the workspace (although it's not a big difference).

As far as I'm concerned, you can close this ticket if you're sure your changes to https://github.com/racket/racket/ fix the problem. Personally, I'd leave the ticket open until Racket 8.3 is released because people coming here with the problem of this ticket are (I think) more likely to look at an open ticket than a closed ticket if they use an up-to-date version of raco cross.

On the other hand, you could argue that this ticket only exists because of a bug in Racket, not raco cross, so there's nothing to fix here anyway. :-D

mflatt commented 1 year ago

Closing, since this issue has been fixed in releases for a while now.