gecko-dev/widget/android/ANRReporter.cpp
Nicholas Nethercote af10e0c45c Bug 1340928 (part 16) - Clean up profiler env var handling. r=mstange.
This patch does the following.

- Uses "entries" consistently for the name of the value that is obtained from
  MOZ_PROFILER_ENTRIES and is the first argument to profiler_start(). (I.e. not
  "entry" or "entrySize".)

- Removes variables (e.g. PROFILER_HELP) holding env var names and uses the
  names (e.g. "MOZ_PROFILER_HELP") directly. Some of the names are already used
  directly and I think the slight repetition isn't harmful. It's unlikely that
  we'd want to change these names the way we might need to change a numeric
  value, and they're perfectly descriptive.

- Changes the "MOZ_PROFILING_FEATURES" string in the weird Android-only startup
  code to be "MOZ_PROFILER_FEATURES", for consistency.

- Renames gUnwindInterval and gProfileEntries as gEnvVarInterval and
  gEnvVarEntries to make it clearer that they come from environment variables,
  but otherwise are parallel to gInterval and gEntries.

- Puts entries before intervals in most places, to match the profiler_start()
  argument order.

- Changes profiler_usage() so that (a) it always prints, no matter the
  verbosity, (b) it exits at its end, and (c) doesn't double-print "Profiler: "
  at the start of each line.

--HG--
extra : rebase_source : e5a0b1c48e390ada894c746f050f08ff5c241066
2017-02-23 14:26:46 +11:00

92 lines
2.8 KiB
C++

/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ANRReporter.h"
#include "GeckoProfiler.h"
#include <unistd.h>
namespace mozilla {
bool
ANRReporter::RequestNativeStack(bool aUnwind)
{
if (profiler_is_active()) {
// Don't proceed if profiler is already running
return false;
}
// WARNING: we are on the ANR reporter thread at this point and it is
// generally unsafe to use the profiler from off the main thread. However,
// the risk here is limited because for most users, the profiler is not run
// elsewhere. See the discussion in Bug 863777, comment 13
const char *NATIVE_STACK_FEATURES[] =
{"leaf", "threads", "privacy"};
const char *NATIVE_STACK_UNWIND_FEATURES[] =
{"leaf", "threads", "privacy", "stackwalk"};
const char **features = NATIVE_STACK_FEATURES;
size_t features_size = sizeof(NATIVE_STACK_FEATURES);
if (aUnwind) {
features = NATIVE_STACK_UNWIND_FEATURES;
features_size = sizeof(NATIVE_STACK_UNWIND_FEATURES);
// We want the new unwinder if the unwind mode has not been set yet
putenv("MOZ_PROFILER_NEW=1");
}
const char *NATIVE_STACK_THREADS[] =
{"GeckoMain", "Compositor"};
// Buffer one sample and let the profiler wait a long time
profiler_start(/* entries */ 100, /* interval */ 10000,
features, features_size / sizeof(char*),
NATIVE_STACK_THREADS,
sizeof(NATIVE_STACK_THREADS) / sizeof(char*));
return true;
}
jni::String::LocalRef
ANRReporter::GetNativeStack()
{
if (!profiler_is_active()) {
// Maybe profiler support is disabled?
return nullptr;
}
// Timeout if we don't get a profiler sample after 5 seconds.
const PRIntervalTime timeout = PR_SecondsToInterval(5);
const PRIntervalTime startTime = PR_IntervalNow();
// Pointer to a profile JSON string
typedef mozilla::UniquePtr<char[]> ProfilePtr;
ProfilePtr profile(profiler_get_profile());
while (profile && !strstr(profile.get(), "\"samples\":[{")) {
// no sample yet?
if (PR_IntervalNow() - startTime >= timeout) {
return nullptr;
}
usleep(100000ul); // Sleep for 100ms
profile = ProfilePtr(profiler_get_profile());
}
if (profile) {
return jni::String::Param(profile.get());
}
return nullptr;
}
void
ANRReporter::ReleaseNativeStack()
{
if (!profiler_is_active()) {
// Maybe profiler support is disabled?
return;
}
profiler_stop();
}
} // namespace