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.23k stars 1.57k forks source link

Regression in StackTrace within `Chain.capture` from `package:stack_trace`. #46326

Open natebosch opened 3 years ago

natebosch commented 3 years ago

Somewhere between 2.12.0-13.0.dev and 2.12.0-29.0.dev there was a regression in StackTrace.current when used within the zone for a Chain.capture call.

Reproduction is using package:stack_trace.

import 'dart:async';

import 'package:stack_trace/stack_trace.dart';

void main() async {
  Future<void> callee() async {
    await Future(() {});
    print(StackTrace.current);
  }

  Future<void> caller() async {
    await callee();
  }

  await Chain.capture(() async {
    await caller();
  });
}

Running with 2.12.0-13.0.dev and earlier SDKs outputs a meaningful stacktrace:

#0      main.callee (package:stack_trace/repro.dart:8:22)
<asynchronous suspension>
#1      main.callee (package:stack_trace/repro.dart)
#2      main.caller (package:stack_trace/repro.dart:12:17)
#3      main.<anonymous closure> (package:stack_trace/repro.dart:16:17)
#4      Chain.capture.<anonymous closure> (package:stack_trace/src/chain.dart:94:24)
#5      _rootRun (dart:async/zone.dart:1190:13)
#6      _CustomZone.run (dart:async/zone.dart:1093:19)
#7      _runZoned (dart:async/zone.dart:1630:10)
#8      runZoned (dart:async/zone.dart:1550:10)
#9      Chain.capture (package:stack_trace/src/chain.dart:92:12)
#10     main (package:stack_trace/repro.dart:15:15)
#11     _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:311:19)
#12     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

Running with 2.12.0-29.dev and later SDKs outputs instead:

#0      main.callee (package:stack_trace/repro.dart:8:22)
<asynchronous suspension>
#1      StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart)
<asynchronous suspension>

The closure it references should be this one:

https://github.com/dart-lang/stacK_trace/blob/4755bcf8ab0258212f4767218fdeb8429f3e550e/lib/src/stack_zone_specification.dart#L126

cc @cskau-g

ghost commented 3 years ago

Thanks Nate. I'll have a look.

ghost commented 3 years ago

Bisects to e90967f29de77f58512499acae471a60f9e42761 which made --lazy-async-stacks default. (My CL)

One thing I notice is that it seems to be a behavioural change specific to StackTrace.current as:

  Future<void> callee() async { ...; throw 'callee throws!'; }
  await Chain.capture(() async { ... }, onError: (e, sc) { print("$e:\n$sc"); });

produces:

callee throws!
dart_46326.dart 9:5    main.callee
===== asynchronous gap ===========================
dart:async/zone.dart 1364:19                        _CustomZone.registerBinaryCallback
dart:async-patch/async_patch.dart 61:8              _asyncErrorWrapperHelper
dart_46326.dart        main.<fn>
package:stack_trace/src/chain.dart 94:24            Chain.capture.<fn>
dart:async/zone.dart 1428:13                        _rootRun
dart:async/zone.dart 1328:19                        _CustomZone.run
dart:async/zone.dart 1863:10                        _runZoned
dart:async/zone.dart 1785:10                        runZoned
package:stack_trace/src/chain.dart 92:12            Chain.capture
dart_46326.dart 17:15  main
dart:isolate-patch/isolate_patch.dart 283:19        _delayEntrypointInvocation.<fn>
dart:isolate-patch/isolate_patch.dart 184:12        _RawReceivePortImpl._handleMessage

which I believe is what you were expecting.

I'll dive into where that difference comes from and what the expected output of StackTrace.current is for this case.

mkustermann commented 3 years ago

@natebosch If you use Chain.capture(), could you then also use Chain.current() instead of StackTrace.current? Would that fix your issue?

natebosch commented 3 years ago

@natebosch If you use Chain.capture(), could you then also use Chain.current() instead of StackTrace.current? Would that fix your issue?

I suspect we could fix it that way. I haven't dug to find how challenging it might be, but it's the first option I describe in https://github.com/dart-lang/stack_trace/issues/111

radzish commented 3 years ago

Hello here, any progress on this?

mraleph commented 1 year ago

I think this is fixed by https://github.com/dart-lang/stack_trace/commit/d3e4c4d633eca379462dd4473b8995761155ee84 and https://github.com/dart-lang/sdk/commit/a52f2b96179ebdf29c38cab47e73dd1c6ec6bdff