Code to reproduce:
class Foo
def initialize
@buffer = Pointer(UInt8).malloc(17)
header = @buffer.as({Int32, Int32, Int32}*)
header.value = {String::TYPE_ID, 4, 0}
end
def to_s
@buffer.as(String)
end
end
string = Foo.new.to_s
data = string.to_slice
if data[0, 4].to_a != [] of UInt8
raise "OH NO!"
end
You have to compile it with --release, then when you run it you get:
Failed to raise an exception: END_OF_STACK
[0x1040f3f27] *CallStack::print_backtrace:Int32 +39
[0x1040ccc90] __crystal_raise +48
[0x1040d2468] *raise<NilAssertionError>:NoReturn +136
[0x1040d2361] *Nil#not_nil!:NoReturn +17
[0x1040f3b97] __crystal_sigfault_handler +55
[0x7fff79632b5d] _sigtramp +29
This was extracted from a larger code that uses String.build, which essentially does the same as Foo.
I don't know what's going on, maybe stack corruption of some sort.
It seems to break when trying to print the backtrace. What happens if you disable it?
similar error on linux and mac, with Crystal 0.31.0 (2019-09-24) LLVM: 8.0.1 Default target: x86_64-apple-macosx with pipes.
crystal --version | echo
Error writing file: Broken pipe (Errno)
from IO::FileDescriptor@Crystal::System::FileDescriptor#unbuffered_write<Slice(UInt8)>:Nil
from IO::FileDescriptor@IO::Buffered#flush:IO::FileDescriptor
from exit<Int32>:NoReturn
from exit:NoReturn
from Crystal::Command#run:(Bool | Crystal::Compiler::Result | Nil)
from __crystal_main
from main
Error: you've found a bug in the Crystal compiler. Please open an issue, including source code that will allow us to reproduce the bug: https://github.com/crystal-lang/crystal/issues
Unhandled exception: Error writing file: Broken pipe (Errno)
from IO::FileDescriptor@Crystal::System::FileDescriptor#unbuffered_write<Slice(UInt8)>:Nil
from IO::FileDescriptor@IO::Buffered#flush:IO::FileDescriptor
from exit<Int32>:NoReturn
from Crystal::error<String, Bool, Int32, IO::FileDescriptor, Bool>:Nil
from Crystal::error:exit_code<String, Bool, Int32>:Nil
from Crystal::Command#error<String, Int32>:Nil
from Crystal::Command#error<String>:Nil
from Crystal::Command#run:(Bool | Crystal::Compiler::Result | Nil)
from __crystal_main
from main
Failed to raise an exception: END_OF_STACK
[0x100b03b17] *CallStack::print_backtrace:Int32 +39
[0x100129b70] __crystal_raise +48
[0x100146a71] *IO::FileDescriptor@Crystal::System::FileDescriptor#unbuffered_write<Slice(UInt8)>:Nil +1057
[0x10012dc4f] main +143
Someone reported this for oq as well https://github.com/Blacksmoke16/oq/issues/39.
Might be related to https://github.com/crystal-lang/crystal/issues/4276
This might get fixed by #8728
I just compiled that code example on 0.33 and 0.34 in both standard and release build and they worked fine; however, this doesn't.
[12:56PM] sandbox$ crystal --version | echo
Error writing file: Broken pipe (IO::Error)
from IO::FileDescriptor@Crystal::System::FileDescriptor#unbuffered_write<Slice(UInt8)>:Nil
from IO::FileDescriptor@IO::Buffered#write<Slice(UInt8)>:Nil
from Crystal::Command#run:(Bool | Crystal::Compiler::Result | Nil)
from __crystal_main
from main
Error: you've found a bug in the Crystal compiler. Please open an issue, including source code that will allow us to reproduce the bug: https://github.com/crystal-lang/crystal/issues
[12:56PM] sandbox$ crystal --version
Crystal 0.34.0 (2020-04-06)
LLVM: 6.0.1
Default target: x86_64-apple-macosx
[12:57PM] sandbox$ ruby --version
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin19]
[12:58PM] sandbox$ ruby --version | echo
So maybe the original issue is fixed, but there's another underlying issue?
This isn't a bug that broken pipe errors exist. I'm glad they display properly now though.
@RX14 The error I posted isn't a bug? If that's the case, then should I open an issue to say that getting that error shouldn't tell us to open an issue about it? On a side note, I can't upgrade to Crystal 0.34 because my Lucky app keeps crashing. This error shows up a lot in my logs, so my thought was that it was related. I don't really understand the error though, so I have no idea.
@jwoertink I think it's totally a bug. It's not bug in the compiler, though. Here's a minimal example that also fails:
# foo.cr:
puts "Hello"
$ crystal foo.cr | echo
Unhandled exception: Error writing file: Broken pipe (IO::Error)
from /usr/local/Cellar/crystal/0.34.0/src/crystal/system/unix/file_descriptor.cr:82:13 in 'unbuffered_write'
from /usr/local/Cellar/crystal/0.34.0/src/io/buffered.cr:218:5 in 'flush'
from /usr/local/Cellar/crystal/0.34.0/src/io/buffered.cr:179:7 in 'write_byte'
...
Could you please fill a separate issue for this?
I'm sorry, I keep forgetting this is not a bug, @RX14 is right and I even wrote this not so long ago: https://github.com/crystal-lang/crystal/issues/7810#issuecomment-585362217
@jwoertink is right though, that the compiler shouldn't crash that way because the stdout is closed. And of course, the message is clear 馃檪
I'd like to see those errors with Lucky to understand if that's related in any way.
@waj https://forum.crystal-lang.org/t/unhandled-exception-error-writing-file-broken-pipe-errno/1396/4 These are the main top of the errors. Beyond those lines just gets in to app specific path stuff.
I'm curious though, I can run that line of code through ruby, and even node without any errors. Do they just swallow that exception? I haven't tried another compiled language, so maybe that's the difference?
@jwoertink let's talk in the issue you just opened so we keep the topic organized for future reference