-
Notifications
You must be signed in to change notification settings - Fork 983
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compile/build problem on RasPi3 #438
Comments
It is very difficult to tell what is going on, except to say that the compiler is likely generating some bad code or the garbage collector is getting some corrupted data from the generated code which is causing it to overwrite something. One thing to try is to compile the compiler and built-in libraries at optimize level 2:
If there is something wrong with the compiler backend for this target, it is likely you'll see some exceptions pop up during the compilation of the compiler and library code. Debugging this kind of thing usually means trying to minimize to as small an example as possible and then running Chez Scheme under I do not have a Raspberry Pi 3 to test on, and currently the only ARM-based machine I have is not setup for this kind of development, but if I get some time I'll see if I can get an emulator running that I can try to replicate this in. The failing I'm assuming this is the 32-bit ARM target that you are using on the Raspberry Pi 3? |
On 2019-06-25 20:16, Andy Keep wrote:
...
One thing to try is to compile the compiler and built-in libraries at
optimize level 2:
$ make o=2 allx
If there is something wrong with the compiler backend for this target,
it is likely you'll see some exceptions pop up during the compilation
of the compiler and library code.
Great. Thanks much. I'll hook up my RasPi3 and check it out.
I'm assuming this is the 32-bit ARM target that you are using on the
Raspberry Pi 3?
Yes. Raspian Linux 32 bit. I don't use it much. My daily use machines
are arm64 (LePotato and Chromebook Plus).
The arm7/32bit is basically to get confidence and learn process/tools,
but I have to make things visible to develop. A bit of debug to get
Chez up on arm32/RasPi would not be bad for the community. 8^)
Thanks for the help!
-KenD
|
Chez Scheme 9.5 worked on armhf. It's a bit cumbersome, because of the image bootstrapping step, but perhaps you could try to do a git bisect to find the commit that broke the arm build? |
Did the "git bisect" but in ignorance ran into process problems. Fortunately, Göran Weinholt is very good at this. He reports
as the first bad commit. |
Indeed, this commit breaks arm32le:
|
Here is some more information that I hope will lead to a solution so that Chez will work on ARM again. It appears that I can reproduce the compilation error (library (lib-2)
(export x y)
(import (rnrs))
(define (x) '(a))
(define (y . _) '(a)))
(library (lib-1)
(export)
(import (rnrs) (lib-2))
(define a
(y (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)))
(define b
(y (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)
(x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x) (x)))) |
This issue pushed me over the edge of buying a Raspberry Pi--I now have a RasPi4 4GB model running Raspbian Buster and was able to reproduce the issue. First off, thank you to @KenDickey and @weinholt for providing so much detail, as it made it relatively easy to narrow in on the source of the problem. That said, I haven't been able to find a solution, since my Chez Scheme hacking chops are a little rusty. The error occurs because the compiler is trying to emit an "add with immediate" instruction ( Once I reproduced the error, I built the compiler with My first thought on seeing this was "why didn't we put in a call to That indicates to me that the instruction is created or exposed after the final round of instruction selection. The breaking changeset that @weinholt identified indeed modifies behavior dealing with how things are stored on the stack (which would involve 1 While I worked on tracking this down, I came across this nice blog post about 12-bit immediate operands on ARM. It both gives a good explanation and provides a handy visual tool for checking if a number can be encoded as a funky12 |
On 2020-02-15 13:37, Chris Frisz wrote:
The error occurs because the compiler is trying to emit an "add with
immediate" instruction (addi) with an invalid immediate value. ...
That indicates to me that the instruction is created or exposed after
the final round of instruction selection.
Great detective work!
The simple solution is to pay a 1 instruction premium for 8..16 bit wide
immediates. [2 instructions]
E.g. [tested on Aarch64; don't have 32 bit ARM OS on hand]
uint32_t word_test() {
asm( "movz x0, #0xCCDD, lsl #0" ) ; /* MoveLo+Zero other bits */
asm( "movk x0, #0xAABB, lsl #16" ) ; /* MoveHi+Keep other bits */
}
==> Immediate inline 32 is 2864434397 = 0xAABBCCDD
…-KenD
[FYI: attached solution for Aarch64 inline 64 bit immediates; no PC reg
available on Aarch64]
|
Essentially, that's what (begin
(set! <reg> #xA01)
(set! %lr (+ %sfp <reg>)) Which should come out to something roughly like this (pardon any assembly mistakes): mov <reg> #0xA01
add %lr %sfp <reg> You do raise a good point: it would be an interesting experiment to disable using funky12 immediate operands for add in |
So I've got good news and bad. The good news is that I found the problem from the original report and the example program, and I have a fix. A bug has been lurking in this version of the ARM code since it was originally written that double-encodes the 12-bit, "funky12" immediates. It would seem that we got away with it for as long as we did because it doesn't affect numbers that fit in 8 bits since the top 4 rotate bits of the funky12 are all 0 anyway. The changeset that @weinholt identified didn't specifically change anything about instruction selection like I suspected, but it did generate code with much larger stack pointer offsets for calls to functions with a large numbers of arguments. As I mentioned before, the immediate from the provided test program fails trying to convert the number 2561 to a funky12, which isn't possible. Examining the output from the pass before The bad news is that even with my fix, there are still errors in the mats. There are at least two kinds of errors. The first set of errors comes from calls to How to fix the The second set of errors from the mats comes from foreign.ms, mostly from the "structs" mat. I haven't dived into it yet, but off the top of my head that indicates that there's something wrong with the alignment and/or offsets that Scheme assumes for structs. Hopefully I can resolve those pretty quickly by writing a little C code that prints out memory addresses and compare it to the offsets the compiler is using for ftypes. I also see some errors from the "varargs" mat, which may or may not get resolved with the same fix. |
@cjfrisz Thanks for looking into this bug; it's blocking me from uploading new Chez Scheme releases to Debian. Could you please share the fixes you have so far? |
@weinholt I apologize for the delay, and I'm sorry this is blocking you. I don't mean to let the perfect be the enemy of the good, but traditionally Chez Scheme has had a "no known issues" policy, so I'm hesitant to submit a patch that doesn't address the bugs in the mats. I've been steadily working on the remaining issues and have a minimized test case for the issue affecting the majority of the foreign.ms mats. Plus, I have an email chain with @akeep where we've discussed how to deal with the timestamp counter. I will continue actively working on this as I have time this week, but can I hold off on making a pull request until this weekend? |
Yes, of course, no worries whatsoever. Everything in its own time. Again, thank you much for working on this! |
I worked on this over the weekend, and the bug in the foreign.ms mats is not as straightforward as I hoped (because of course it's not). Here's a relatively minimized version of one of the test that's failing: (begin
(load-shared-object "./f4_sum_cb_i8.so")
(load-shared-object "libc.so.6")
(define-ftype callback-r (function () (& integer-8)))
(define sum_cb (foreign-procedure "f4_sum_cb_i8"
((* callback-r)) double))
(let ([cb (make-ftype-pointer
callback-r
(lambda (r)
(ftype-set! integer-8 () r -11)))])
(let ([v (sum_cb cb)])
(unlock-object
(foreign-callable-code-object
(ftype-pointer-address cb)))
v))) And the corresponding C code, assumed in Scheme to be compiled to double f4_sum_cb_i8 (signed char (*cb)()) {
signed char v = cb();
return (double)v;
} Essentially, the test binds a I did some time in gdb, and the invalid memory reference occurs in the There are other tests for Probably the most direct way to debug this is to validate that the ftype-pointer that gets allocated has the correct shape according to the runtime. My skills for digging around in memory with gdb and figuring out the correct offsets are a little rusty, so that's the major slowdown. I'm still reluctant to do a pull request claiming to fix the arm32le support when this is lurking in there. Are you pushing releases specifically for Debian ARM, or is there a way to leave off the ARM version until this is really fixed? |
I'm pushing releases for all architectures at the same time (i386, amd64 and armhf for now; ppc was already broken, #302). I can't leave one off, but it's ok, take the time you need. A PR doesn't need to be complete from the very start though and it can help you get more eyes on the problem. |
The f4_sum_cb_i8 example works for my old RPi with an old Raspian, so I'm not certain what's going wrong. But the last sub-case of the https://github.com/cisco/ChezScheme/blob/master/s/arm32.ss#L2977 That's always reading 4 bytes from some space the stack, and maybe on an little endian machine, an 8-byte result doesn't get sign extended as it should be. It's not right at all for big-endian. Maybe the implementation there should instead be analogous to the ppc32 case: https://github.com/cisco/ChezScheme/blob/master/s/ppc32.ss#L2984 Also, it looks like the result registers on lines 2978 and 3006 should be The varargs failure may be because the ABI distinguishes variadic functions where FP registers should not be used for arguments. If so, Chez Scheme will need a new calling-convention option so specific varargs mode, and then the arm32 implementation can skip registers. |
Thanks for taking a look at that! I was kind of dreading the next round of debugging (and put it off for a while). This gives me some very good leads to go off of. |
I've spent more time on arm32le, so here are some follow-ups:
|
Last I was debugging the
I don't have access to my notes at the moment, but if I remember correctly, I found advice for a similar error to use |
The |
Yes, that's right. At some point my changeset included an update to use |
I'm pretty sure this is all resolved, so closing. |
Greetings,
First, thanks much for making Chez Scheme open source!!
I have been trying to get Chez up on a Raspberry Pi 3 under Raspian Linux, roughly following the guide at:
https://programmingpraxis.com/2017/09/15/compile-chez-scheme-on-android-arm/
The basic REPL is fine for small things, but some library loads fail with
The test suite also shows this behavior.
Perhaps a codegen in FFI call?
Any suggestions?
Thanks much,
-KenD
akku-compile-bug.txt
mats-summary.txt
The text was updated successfully, but these errors were encountered: