Skip to content

Commit e279b3c

Browse files
authored
Detect and error on failed codegen process (#14762)
Report an exception when it occurs in a codegen forked process, otherwise detects when a codegen process terminated early (which is what happens on LLVM error). In both cases a BUG message is printed on stderr and the main process exits.
1 parent 057771f commit e279b3c

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

src/compiler/crystal/compiler.cr

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,9 @@ module Crystal
533533
result = {name: unit.name, reused: unit.reused_previous_compilation?}
534534
output.puts result.to_json
535535
end
536+
rescue ex
537+
result = {exception: {name: ex.class.name, message: ex.message, backtrace: ex.backtrace}}
538+
output.puts result.to_json
536539
end
537540

538541
overqueue = 1
@@ -554,13 +557,21 @@ module Crystal
554557
while (index = indexes.add(1)) < units.size
555558
input.puts index
556559

557-
response = output.gets(chomp: true).not_nil!
558-
channel.send response
560+
if response = output.gets(chomp: true)
561+
channel.send response
562+
else
563+
Crystal::System.print_error "\nBUG: a codegen process failed\n"
564+
exit 1
565+
end
559566
end
560567

561568
overqueued.times do
562-
response = output.gets(chomp: true).not_nil!
563-
channel.send response
569+
if response = output.gets(chomp: true)
570+
channel.send response
571+
else
572+
Crystal::System.print_error "\nBUG: a codegen process failed\n"
573+
exit 1
574+
end
564575
end
565576

566577
input << '\n'
@@ -578,11 +589,18 @@ module Crystal
578589
end
579590

580591
while response = channel.receive?
581-
next unless wants_stats_or_progress
582-
583592
result = JSON.parse(response)
584-
all_reused << result["name"].as_s if result["reused"].as_bool
585-
@progress_tracker.stage_progress += 1
593+
594+
if ex = result["exception"]?
595+
Crystal::System.print_error "\nBUG: a codegen process failed: %s (%s)\n", ex["message"].as_s, ex["name"].as_s
596+
ex["backtrace"].as_a?.try(&.each { |frame| Crystal::System.print_error " from %s\n", frame })
597+
exit 1
598+
end
599+
600+
if wants_stats_or_progress
601+
all_reused << result["name"].as_s if result["reused"].as_bool
602+
@progress_tracker.stage_progress += 1
603+
end
586604
end
587605

588606
all_reused

0 commit comments

Comments
 (0)