Skip to content

Commit

Permalink
Ensure LibUnwind::Exception struct is not atomic
Browse files Browse the repository at this point in the history
  • Loading branch information
waj committed Jan 31, 2020
1 parent 7fc7379 commit c48484e
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 4 deletions.
5 changes: 5 additions & 0 deletions spec/std/data/collect_within_ensure
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
begin
raise "Oh no!"
ensure
GC.collect
end
25 changes: 24 additions & 1 deletion spec/std/exception_spec.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
require "spec"
require "./spec_helper"

private def compile_and_run_file(source_file)
with_tempfile("executable_file") do |executable_file|
Process.run("bin/crystal", ["build", "--release", "-o", executable_file, source_file])
File.exists?(executable_file).should be_true

output, error = IO::Memory.new, IO::Memory.new
Process.run executable_file, output: output, error: error

{output.to_s, error.to_s}
end
end

private class FooError < Exception
def message
Expand Down Expand Up @@ -34,4 +46,15 @@ describe "Exception" do
ex.inspect_with_backtrace.should contain("Caused by")
ex.inspect_with_backtrace.should contain("inner")
end

it "collect memory within ensure block" do
sample = datapath("collect_within_ensure")

output, error = compile_and_run_file(sample)

output.to_s.empty?.should be_true
error.to_s.should contain("Unhandled exception: Oh no! (Exception)")
error.to_s.should_not contain("Invalid memory access")
error.to_s.should_not contain("Illegal instruction")
end
end
2 changes: 1 addition & 1 deletion src/callstack/lib_unwind.cr
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ lib LibUnwind
exception_cleanup : LibC::SizeT
private1 : UInt64
private2 : UInt64
exception_object : UInt64
exception_object : Void*
exception_type_id : Int32
end

Expand Down
4 changes: 2 additions & 2 deletions src/raise.cr
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ end

# :nodoc:
fun __crystal_get_exception(unwind_ex : LibUnwind::Exception*) : UInt64
unwind_ex.value.exception_object
unwind_ex.value.exception_object.address
end

# Raises the *exception*.
Expand All @@ -218,7 +218,7 @@ end
unwind_ex = Pointer(LibUnwind::Exception).malloc
unwind_ex.value.exception_class = LibC::SizeT.zero
unwind_ex.value.exception_cleanup = LibC::SizeT.zero
unwind_ex.value.exception_object = exception.object_id
unwind_ex.value.exception_object = exception.as(Void*)
unwind_ex.value.exception_type_id = exception.crystal_type_id
__crystal_raise(unwind_ex)
end
Expand Down

0 comments on commit c48484e

Please sign in to comment.