React-native: TypeError: global.nativeTraceBeginSection is not a function (Systrace)

Created on 13 Jul 2017  Ā·  69Comments  Ā·  Source: facebook/react-native

Is this a bug report?

Yes

Have you read the Bugs section of the Contributing to React Native Guide?

Yes

Environment

  1. react-native -v: react-native-cli: 2.0.1, react-native: 0.46.1
  2. node -v: v7.10.0
  3. npm -v: 4.6.1
  4. yarn --version (if you use Yarn): Not used in this bug

Then, specify:

  • Target Platform: iOS

  • Development Operating System: macOS Sierra v 10.12

  • Build tools: Xcode Version 8.3.3 (8E3004b)

I'm running react-native run-ios deploying to iOS emulator Version 10.0 (SimulatorApp-745.10), running iOS 10.3 in an iphone 6.

Steps to Reproduce

(Write your steps here:)

  1. Run react-native run-ios with Systrace enabled

dev_menu

  1. Reload your app (manually or with live/hot reload)

  2. Check the logs

Expected Behavior

The app should reload normally.

Actual Behavior

The error TypeError:global.nativeTraceBeginSection gets launched into the console:

console_error

And in the UI:

ui_error

After that, the whole emulator crashes and the only way to restore it is running react-native run-ios again.
One temporary workaround to get rid of this error is disabling Systrace in the DevMenu, but this is less than ideal.

Reproducible Demo

https://snack.expo.io/ryCtYZHrZ

Observation: Even though I included a snack, I'm afraid you can't fully reproduce this problem without a Mac and an iOS emulator, the reason being that the Systrace is not an Expo function.

Bug Debugging Author Provided Repro Systrace

Most helpful comment

Following steps help me:

  • Press Cmd+D (or shake the device )to show the Dev menu.
  • Select Stop Systrace option.
  • Restart the app.

All 69 comments

I just discussed this with @javache and it seems like the issue is that Systrace is currently broken with the c++ bridge because the module currently doesn't get compiled for the OSS build.

For some reason I did not get that crash but instead no JS trace were reported in the trace I recorded.

@janicduplessis any idea when a fix for this will be pushed? This is causing serious development time problems for me.

Same problem on v0.47, I was hoping for this commit by @gaearon to fix systrace, but it seems for some reason it still doesn't work ĀÆ\_(惄)_/ĀÆ

I didnā€™t fix anything related to C++ bridge.

Ops, thanks for the clarification and sorry about the confusion! Let's hope for that C++ bridge fix!

I'm aware of this issue. We currently don't have these methods on the C++ bridge since the C++ implementation depends on fbsystrace, which is not open-source. As a workaround, you can revert back to RCTBatchedBridge (ReactLegacy), we'll try to find a solution for this soon.

@javache what would be the process to "revert to RCTBatchedBridge"? Do you mean just using and older RN release?

As explained in #15371, without systrace and without proper JS remote debugging, with the current release of RN is quite hard to debug any performance problem, so any guidance on how to do this would be more than appreciated! Thanks!

Does anyone have any workarounds for this? Or any hints about how to revert to RCTBatchedBridge. Seems like this was a pretty vital part of the RN development process, how on earth does one fix performance issues without being able to see where they are?

Ok, here's how to switch back to RCTBatchedBridge. First you need to make sure the bridge is being created with a delegate, I think this might be default for new projects but if you have an existing project you may need to change it. Here's the code from my AppDelegate.m:

  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self
                                         launchOptions:launchOptions];

  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"yourapp" initialProperties:nil];

You then need the delegate method for getting the sourceURL and ALSO a new method called "shouldBridgeUseCxxBridge" to tell RN not to use the CxxBridge. Both of these should be added to AppDelegate:

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
}

- (BOOL)shouldBridgeUseCxxBridge:(RCTBridge *)bridge {
  return NO;
}

At this point your project will crash when you start it. The files needed for the BatchedBridge aren't included in the xcode project. So you'll need to add them by right clicking on React.xcodeproj in xcode and selecting Add files to "React.xcodeproj". You need the following files:

./node_modules/react-native/React/Base/RCTBatchedBridge.mm
./node_modules/react-native/React/Executors/
./node_modules/react-native/React/Profiler/RCTJSCProfiler.h
./node_modules/react-native/React/Profiler/RCTJSCProfiler.m

You should now be able to start the project and use SysTrace again!

Of course you have to re-add those files every time you setup the code, those changes won't be saved to git. I'm sure you could add a script to do it to package.json's install section but I'm really hoping this gets fixed properly soon as I'm sure people outside Facebook also need to write React Native apps that don't suck (and I don't see how to do that without SysTrace to make them fast).

@almost thank you so much! And I absolutely agree that we need to get this fixed properly, not having systrace makes improving performance problems almost impossible.

@almost I followed your instructions and now I can do the systrace and generate the json file, however when I open it with Chrome tracing I just see calls to RCT* stuff, I can't see any of the JS calls I used to see before. Are you experiencing the same? Thanks!

It's working ok for me, I'm seeing the JS trace points as well as the native ones. I'm on RN version 0.46.1, not sure if that makes a difference. Could be related to @gaearon's commit you mentioned above...

Thanks! I was using v0.47, after downgrading to 0.46.1 and repeating the same steps now I can see some of my JS calls.

However with 0.46.1 I can't still see traces for the full JS execution:

image

I see this CalendarMonth.render() (one of my components) that takes 2 seconds but I cannot dig any further than that šŸ˜”

That's most likely because CalendarMonth.render isn't instrumented. Systrace isnt like a JS profile you'd get from Chrome. It relies on explicit calls to the systrace functions to let it know when things start and stop. React Native includes a bunch of calls but you can always instrument your own code. It even supports async code (will be shown in a separate track) which can be very useful.

If you wanted a JS profile it might be worth using Remote JS Debugging then running the profile in Chrome. Obviously you'll get different performance characteristics in Chrome, but it can still give you a good idea of what's causing a problem. But for most RN performance problems I find Systrace far more helpful.

I think I remember in the past using systrace and getting detailed calls beyond render(), but I can't be 100% sure, maybe I was using remote JS debugging, not systrace.

The problem with Remote JS debugging in this case is that the JS code is the bottleneck (not the RN bridge), and the remote debugger makes JS much faster than in a normal device / simulator, making debugging the bottleneck not that easy.

I'll try adding some instrumentation to my code as you suggested, thanks!

PS: sorry for hijacking the thread a little bit, but given the current situation of profiling with the latest versions of RN, I think this kind of stuff may be interesting for other people.

Using React Native 48.4 and React 16.0.0-alpha.12 I cannot use the fix provided by @almost

These files do not exist
./node_modules/react-native/React/Profiler/RCTJSCProfiler.h
./node_modules/react-native/React/Profiler/RCTJSCProfiler.m

I just started learning React Native today and downloaded everything fresh. Getting the exact same error on a "hello, world" app:

global.nativeTraceBeginSection is not a function

How is anyone using React Native to build apps if the simplest app won't run?

For android ? AFAIK it has never be working on android due to missing fbsystrace.h
Some of issues iceboxed recently https://github.com/facebook/react-native/issues/14394 https://github.com/facebook/react-native/issues/15022
Any help is appreciated.

While this is not fixed,
any other way to profile react native performance like we can do on react for web?

A way that shows the render time for each component (flame graph).

I donā€™t have background on this issue but itā€™s weird that itā€™s broken. Iā€™m fairly sure I had this working about a couple of months ago.

As a temporary workaround, I think enabling Chrome debugging might work? Then in the Perfromance tab of Chrome you can ā€œrecordā€ and see measurements in the User Timing subsection. Give it a try and let me know.

@gaearon nope, doesn't work with or without chrome debugging enabled.
Also with or without xcode attached.

systrace-bug.gif

in the Perfromance tab of Chrome you can ā€œrecordā€ and see measurements in the User Timing subsection.

This works! After a few attempts, I just had to change the thread to debuggerWorker.js on the Chrome's Sources tab šŸ™ŒšŸ™Œ (edit: check comment bellow, it's not Source it's Bottom Up tab)
Thanks.

~This isn't specified in the docs so created this PR: https://github.com/facebook/react-native-website/pull/54~

image

image
image

Okay, re-reading the thread I understand why it wasnā€™t broken when I tested it: we have a fork of this at FB. So it still works for us, but is broken in open source. This is not great, and Iā€™ll try to figure out what the next steps here are by chatting to someone internally.

That said the workaround in https://github.com/facebook/react-native/issues/15003#issuecomment-350559040 can at least give you the React timings, so while itā€™s not ideal I hope it helps in the meantime.

Iā€™ve brought it up internally, and thereā€™s a person who planned to look into fixing this either in December on January. If itā€™s not fixed by the end of January please ping me in person (e.g. on Twitter DM) and Iā€™ll try to see whatā€™s the status on this.

@gaearon Ok, thanks Dan!

I just tried this. Changing the thread in sources didn't matter to me. What mattered was changing the thread in the Bottom-Up tab, bottom half of Performance.

image

@brunolemos Mind checking if that matters in your experience?

@gaearon He is right, sources doesn't have any effects after all. Turns out the flame graph always shows correctly under User timing no matter what thread is selected. Selecting DedicatedWorker Thread also doesn't change the flame graphs but does change the content of the Bottom Up panel.

@gaearon @kralcifer-ms this should be correct now, please review: https://github.com/facebook/react-native-website/pull/63

So to summarize, there is no problem with the chrome profiling, just the systrace.

@gaearon Any update on this? Using the chrome profiler won't give an accurate representation AFAIK.

If there was an update, it would be on this issue.

As I mentioned above:

If itā€™s not fixed by the end of January please ping me in person

@gaearon Just checking in now we're post January and the issue's still open! Any updates here? Thanks!

@gaearon ping again! It is now middle february and still no update on the systrace fix

@gaearon In some parts of the world its March now! Friendly ping to get an update on the much needed systrace :))

Friendly ping, @gaearon.

It's not even possible to hack Systrace into working anymore, since RCTBatchedBridge was fully removed in v0.54.0.

This issue represents a major problem I have with React Native maintainership. Facebook contributors originally broke Systrace, but because Facebook has a working internal Systrace implementation, they don't feel enough pain to fix this issue.

(One could argue that the external community should've fixed this problem by now, but I would bet a non-trivial sum of money that if a non-core contributor opened a PR that plumbed systrace hooks through a bunch of C++ code, it would _not_ be given a serious review.)

When this happened to me, in the iOS simulator, from the "Hardware" menu, I triggered the "shake gesture", then chose "Disable Remote JS Debugging", then repeat the process to enable it again. Error was gone.

This came up out of the blue for me while developing an app. Doing what @antoniobrandao suggested worked for me; turned off all debugging and reloading, closed app in simulator, then reloaded. No idea what triggered it, but I imagine it was related to hot-reloading and the JS Debugger running in tandem on the IOS app. FWIW the Android simulator had no problems.

I uninstalled the app from ios simulator, run it from xcode and it's works

Sorry, when I said ā€œin personā€ I didnā€™t mean on GH :-(. I donā€™t subscribe to GH issues, there is too much noise. So I missed all of these comments. I meant to use something like Twitter.

Iā€™ll ask again.

ReactNative 0.55.4 here, and I'm unable to get sys trace to work.... (no remote debug activated, no live reload, clean install of app from terminal or Xcode => I get the error screen in any case....)

@wynch
found in https://stackoverflow.com/questions/49340074/chrome-debug-tools-for-react-native-mutiple-issues/49676564

ctrk+m on your emulator.
click on Dev Settings.
Disable Use JS Delta
restart the react native server.

then Go to http://localhost:8081/debugger-ui/ . Then stop remote js debugging and run your react native app again. Finally debug js remotely.

This worked for me

perf measurements using chrome debugging are not very useful for tuning the app in a real world context, since its using the chrome js engine. this is quite a gaping hole in this whole react-native thing.

Well, this is exciting: As of RN 0.56, this seems to crash with a slightly different error message. Instead of nativeTraceBeginSection, it now complains that global.pokeSamplingProfiler is not a function.

image

Following steps help me:

  • Press Cmd+D (or shake the device )to show the Dev menu.
  • Select Stop Systrace option.
  • Restart the app.

@gaearon is correct that we have one version of the profile internally which is what we use for profiling our apps.

I am looking to see the parts that are missing and see how we can make the profiler work on android.
For iOS, looks like the C++ implementation is missing. If anyone in the community wants to take a stab at it, let me know and I can give you a very old PR that attempts to fix this. You could use this as a starting point to see how this can be fixed.

@axemclion ā€” I'll happily bite. Please point me towards the old PR.

@GuoZhiQiang hi, bc this problem when I shake the device the dev menu didn't open, so where should I press the cmd+R (im talking about physical device)?

@gaearon, just checking in again to see if this issue was ever addressed in a more comprehensive way. I'm running 0.54 and at the moment it looks like there's no good way to profile the RN portions of our app. Is that correct?

I came here with the same question -- running 0.57 and I can't seem to find a way to profile the RN portions. Trying to enable Systrace (to use custom markers) results in the same error as reported above, and trying to use Start/Stop Sampling Profiler ends with the same issue in https://github.com/facebook/react-native/issues/18044

For those curious, I got systrace working on Android. I also got a ton of other metrics that you can use. More details - http://blog.nparashuram.com/2018/11/react-native-performance-playbook-part-i.html.

While this is for Android only for now, i will work on iOS next.

The Facebook team are soliciting feedback about debugging react native apps over in the "discussions and proposals" repository. I posted a summary about this Systrace issue to bring it to their attention. Feel free to leave a šŸ‘ over there if this issue is affecting you:

https://github.com/react-native-community/discussions-and-proposals/issues/69#issuecomment-446115060

Great recap @matt-oakes, thank you! Let's hope it gets some attention.

I am getting this error in RN 0.59. Any ideas?

I am getting this error in RN 0.60.3 and Stop Systrace dos'nt work and any message from debug console

This is a known problem, and systrace is not enabled yet on iOS.

In the meantime, you could use Safari to get Sampling profiler working on JSC. Its not everything that systrace can give you, but could still be useful stop gap till systrace issue is fixed.

Here is how I got safari working with JSC for sampling profiler

https://twitter.com/nparashuram/status/1153369115962302465

I also have this problem, but when I changed General > Bundle Identifier back to the default name, I found this problem no longer happened.

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.

This is still an issue on 0.61.

Is it possible to revert to the old bridge in RN 0.61 using CocoaPods? The instructions posted above by @almost don't apply anymore because there is no React.xcodeproj in my workspace...

After some digging, it looks like JSCTracing.cpp, which previously provided the global.nativeTrace* methods in js, were removed with RN 0.58.0.

edit: github was hiding a bunch of comments, I now see that the batched bridge was also removed before the tracing methods were :/

What are people using to debug JS-side performance issues in RN? Recording a session in the performance tab of dev tools doesn't seem to provide any level of detail whatsoever - I just see Task and Function Call, and things like that. :/

Stop and resatrt app

I just had a go at _hacking_ the RCTProfile implementation (v0.60.4) and I managed to get the native part going but now I'm struggling with the JS side.

Screenshot 2020-02-05 at 15 31 30

After some digging, it looks like JSCTracing.cpp, which previously provided the global.nativeTrace* methods in js, were removed with RN 0.58.0.

@zcramos, I'm trying to understand how JSCTracing fits into the big picture with 0.60.4, but it's proving to be quite a problem.

2.5 years later, this is still broken and systrace is still in the official docs as a debugging tool. Here's another related issue: https://github.com/facebook/react-native/issues/26032

Has anybody found alternative methods of profiling performance on Android? Chrome devtools don't give accurate results, react-devtools profiler appears to be broken... It seems there are no options left for perf debugging on Android.

It looks like the folks over at microsoft/react-native-windows have their own implementation of fbsystrace.h thats been mentioned earlier in this thread - fbsystrace.h.

My C++ knowledge is lacking/non-existent but would this mean the C++ bridge could be recompiled with proper systrace support if this was included?

@axe-fb are we doing something wrong? Is Systrace now permanently broken for Android now that global.nativeTraceBeginSection is missing?

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

This is still an issue. 3 years and counting, can we at least get systrace removed from the docs since it hasnā€™t worked for 3 years?

Was this page helpful?
0 / 5 - 0 ratings