dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.19k stars 1.56k forks source link

Program triggers segfault in JIT mode, runs fine on AOT/exe #50622

Closed tamcy closed 1 year ago

tamcy commented 1 year ago

Dart SDK Version (dart --version): Dart SDK version: 2.19.0-374.1.beta (beta) (Tue Nov 15 07:44:30 2022 -0800) on "windows_x64"

I encontoured a rather confusing issue when running a Dart command line program. When running with dart run in the terminal the program just stops prematurely without any error message. I then tried running in debug mode using Android Studio, and while there is still no error nor exception, the following message emitted in the middle of the execution:

Process finished with exit code -2147483645

At first, I was unable to find out where the program ends with breakpoints (the program finishes successfully). Then I tried removing the breakpoints and insert various print messages here and there. After that I am quite sure there's something wrong with the execution because the program can stop at a very strange place, like after the if statement and before the for statement. The program processes a set of data in a loop, but it isn't any particular data that causes the program to stop - the data that fails runs fine if I move it to the first of the loop.

Some additional observations:

I am willing to contribute the code privately for reproducting this issue, but I need some time to remove the unnecessary noises (it's still under development). The code is about detecting overlapping curves by using the intersectionsWithCurve() function in the beizer package. The function will be called multiple times in a loop. While I suppose this is a relatively heavy computation, memory should not be a program (I have over 30GB free memory), and the program stops very early.

I know there isn't very much useful information provided, please see if you can provide any suggestion on the issue I encountered. Thank you!

srawlins commented 1 year ago

Loosely triaging this to VM...

tamcy commented 1 year ago

Here is an update to the issue I have reported. The code that reproduces this issue can be found at https://github.com/tamcy/dart-issue-50622.

When running on Docker, I can finally see the following segfault messages emitted in the middle of the loop:

===== CRASH =====
si_signo=Trace/breakpoint trap(5), si_code=128, si_addr=(nil)
version=2.19.0-374.2.beta (beta) (Wed Nov 23 12:15:38 2022 +0000) on "linux_x64"
pid=1, thread=16, isolate_group=main(0x561e8f4f6000), isolate=main(0x561e8f5dc000)
os=linux, arch=x64, comp=no, sim=no
isolate_instructions=561e8d134360, vm_instructions=561e8d134360
  pc 0x00007f17453cd887 fp 0x00007f1740bfe050 Unknown symbol
  pc 0x00007f17453b8ad8 fp 0x00007f1740bfe0e8 Unknown symbol
  pc 0x00007f17453b7e5b fp 0x00007f1740bfe178 Unknown symbol
  pc 0x00007f17453ad9af fp 0x00007f1740bfe1e8 Unknown symbol
  pc 0x00007f17453ad7de fp 0x00007f1740bfe260 Unknown symbol
  pc 0x00007f17453ad34c fp 0x00007f1740bfe2c0 Unknown symbol
  pc 0x00007f17453ac32b fp 0x00007f1740bfe310 Unknown symbol
  pc 0x00007f17453a3dd2 fp 0x00007f1740bfe350 Unknown symbol
  pc 0x00007f17453a3c0c fp 0x00007f1740bfe380 Unknown symbol
  pc 0x00007f17453a2d9f fp 0x00007f1740bfe3e8 Unknown symbol
  pc 0x00007f17453a303b fp 0x00007f1740bfe428 Unknown symbol
  pc 0x00007f17453a2d9f fp 0x00007f1740bfe490 Unknown symbol
  pc 0x00007f17453a25e1 fp 0x00007f1740bfe4e8 Unknown symbol
  pc 0x00007f174be02ffc fp 0x00007f1740bfe560 Unknown symbol
  pc 0x0000561e8d2a8949 fp 0x00007f1740bfe600 dart::DartEntry::InvokeCode(dart::Code const&, unsigned long, dart::Array const&, dart::Array const&, dart::Thread*)+0x139
  pc 0x0000561e8d2a87c5 fp 0x00007f1740bfe660 dart::DartEntry::InvokeFunction(dart::Function const&, dart::Array const&, dart::Array const&, unsigned long)+0x145
  pc 0x0000561e8d2aab24 fp 0x00007f1740bfe6a0 dart::DartLibraryCalls::HandleMessage(long, dart::Instance const&)+0x144
  pc 0x0000561e8d2cde58 fp 0x00007f1740bfec30 dart::IsolateMessageHandler::HandleMessage(std::__2::unique_ptr<dart::Message, std::__2::default_delete<dart::Message>>)+0x348
  pc 0x0000561e8d2f608a fp 0x00007f1740bfecb0 dart::MessageHandler::HandleMessages(dart::MonitorLocker*, bool, bool)+0x15a
  pc 0x0000561e8d2f67ab fp 0x00007f1740bfed00 dart::MessageHandler::TaskCallback()+0x1db
  pc 0x0000561e8d41bb9b fp 0x00007f1740bfed80 dart::ThreadPool::WorkerLoop(dart::ThreadPool::Worker*)+0x13b
  pc 0x0000561e8d41bfe8 fp 0x00007f1740bfedb0 dart::ThreadPool::Worker::Main(unsigned long)+0x78
  pc 0x0000561e8d392906 fp 0x00007f1740bfee70 dart+0x21b4906
-- End of DumpStackTrace

===== CRASH =====
si_signo=Segmentation fault(11), si_code=128, si_addr=(nil)
Aborting re-entrant request for stack trace.

When running on Windows in debug mode, the code terminates with exit code -2147483645. No error message is printed. But occasionally a message similar to the following is emitted (yet I counter the message just once in tens of the executions):

Error: Failed to send request: {"jsonrpc":"2.0","id":"9","method":"setExceptionPauseMode","params":{"isolateId":"isolates/3021199231267163","mode":"Unhandled"}}

I have tested the code against several versions on Docker. The code crashes on dart:2.19.0-374.2.beta, dart:2.19.0-374.1.beta, dart:2.19.0-255.2.beta and dart:2.19.0-146.1.beta. It runs fine on dart:2.18.5.

mraleph commented 1 year ago

@tamcy please add some open-source license of your choice to the repo, otherwise we can't look at it. (e.g. MIT, BSD, GPL, LGPL, Apache, etc.).

tamcy commented 1 year ago

@mraleph No problem, MIT license file added to the repo.

mraleph commented 1 year ago

Would you have some free cycles to take a look at this @aam?

aam commented 1 year ago

dart --optimization-counter-threshold=2 bin/demo.dart seems to reliably reproduce the breakpoint trap which is inserted by https://github.com/dart-lang/sdk/blob/main/runtime/vm/compiler/backend/flow_graph.cc#L1950. There somehow seems to be a confusion whlie optimizing/inlining package:bezier/src/bezier.dart_Bezier__nonOverlappingNormalVectorAt where UnboxedFloat is attempted to be converted to UnboxedDouble

aam commented 1 year ago

Problem seems to be with https://github.com/dart-lang/sdk/blob/main/runtime/vm/compiler/backend/flow_graph.cc#L2056 where PhiInstruction gets unboxed double representation even if incoming values are unboxed floats. Something like https://dart-review.googlesource.com/c/sdk/+/275180 seems to fix the crash.

mraleph commented 1 year ago

Makes sense. The fix should be fixed-point based, because you can have float phis flowing into other phis. So it should likely follow the same template that HasUnboxedIncomingValue has.