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.09k stars 1.56k forks source link

Get Dart StackTrace via public API #36865

Open dnfield opened 5 years ago

dnfield commented 5 years ago

Use case:

In Flutter Engine, we sometimes get crash reports where the C++ code has no real useful information for us - e.g. there's a state issue that was introduced by Dart code and we're likely just missing an assert or guard. However, we can sometimes only guess at how that state was arrived at, and whether it was something in framework code or consuming user code.

It would be great if we could print the Dart stack trace before calling abort in some of our checks on the C++ side. I basically want the function in gdb_helpers.cc to be public, perhaps only if we're not in PRODUCT (i.e. it would be ok for this to be a no-op for PRODUCT). Ideally this is something that would get exposed via dart_api.h.

/cc @sjindel-google @cbracken @Hixie @jason-simmons

sjindel-google commented 5 years ago

/cc @rmacnak-google probably has an opinion about this, given that it's related to the profiler.

a-siva commented 5 years ago

I am assuming you have an unhandled exception object in the C++ code when this happens, Could you use the API call Dart_ErrorGetStackTrace to get a stack trace object and then print it using Dart_ToString?

dnfield commented 5 years ago

The intended use case for this is an exception in the embedding code, where Dart does not have an exception.

For example, in an accessibility bridge we might do something that results in an NPE based on conditions we believe should never happen - Dart hasn't done anything it sees as wrong, but we'd like to know what the stack looks like in Dart before it made a call that resulted in any native code.

This may not be as helpful as we always want, but sometimes it seems like it could be.

dnfield commented 5 years ago

IOW, if we have a crash on the C++/Java/Objective C side, it might be helpful to also dump the Dart stack in the output.

fzyzcjy commented 2 years ago

Hi, is there any updates? I hope to implement a simple profiler, which samples the stack trace at (say) 1000Hz and draw a framegraph, in production builds.

dnfield commented 2 years ago

Dart already has a cpu profiler.

I strongly doubt you'd be able to meaningfully get the stack trace without destroying performance at that sampling rate though.

fzyzcjy commented 2 years ago

@dnfield Thanks! But I hope I can profile my app in production (release) mode. The specific use case: Sometimes the users will feel the app being slow and jank, but I cannot reproduce easily by myself. Thus, it is hard to utilize the dart CPU profiler, since profiler only works when in profile mode and device connected to computer :(

fzyzcjy commented 2 years ago

@dnfield Could you please suggest what I should do for that case? Thanks!

dnfield commented 2 years ago

Calling getStackTrace over and over again (even in release mode, assuming such an API would even be supported in release mode), will cause jank by itself.

For reproducing jank, you'll want to reproduce that jank part of your app as close to the application state your users have as possible and on the same device as your users are using. Then you'll want to use existing profiling tools to investigate more about what's going on.

Knowing the stack trace is unlikely to be helpful - for example, what would you do with 4-500 frames of widget building if that turns out to be the issue? You'll want to know what else was going on in the device. Alternatively, what will you do if it turns out the jank is all on the raster thread, which isn't running Dart code at all?

fzyzcjy commented 2 years ago

@dnfield Thanks for your insights! I agree with you.

For reproducing jank, you'll want to reproduce that jank part of your app as close to the application state your users have as possible and on the same device as your users are using. Then you'll want to use existing profiling tools to investigate more about what's going on.

The problem is that jank is hard to reproduce :( Anyway I will try.

Knowing the stack trace is unlikely to be helpful - for example, what would you do with 4-500 frames of widget building if that turns out to be the issue? You'll want to know what else was going on in the device. Alternatively, what will you do if it turns out the jank is all on the raster thread, which isn't running Dart code at all?

Good question!

fzyzcjy commented 2 years ago

@dnfield

In my case, I suspect the jank is because there are some of my dart code that is running more frequently/heavily than expected. In other words, the jank is (guessed) unrelated to Flutter framework. So hopefully the stack trace will be all about my own Dart code, then I can spot the problem very quickly.

In addition, I see simpleperf can sample 1000Hz (and even 4000Hz using call graph mode) without affecting performance. Can Dart make use of it?

Thanks!