MCPcopy Create free account
hub / github.com/Snapchat/Valdi / onANR

Method onANR

valdi/src/valdi/runtime/JavaScript/JavaScriptANRDetector.cpp:131–199  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

129}
130
131bool JavaScriptANRDetector::onANR(JavaScriptTaskScheduler& taskScheduler,
132 std::chrono::steady_clock::duration detectionThreshold,
133 const std::atomic<bool>& ack) {
134 auto stacktraces = taskScheduler.captureStackTraces(std::chrono::seconds(kCaptureStacktraceTimeoutSeconds));
135 StringBox moduleName;
136 std::string message;
137
138 if (!stacktraces.empty() && stacktraces[0].getContext() != nullptr) {
139 moduleName = stacktraces[0].getContext()->getPath().getResourceId().bundleName;
140 }
141
142 if (!hasRunningStacktrace(stacktraces) && ack.load()) {
143 // The ack was submitted while waiting to capture stacktraces.
144 // We consider that task scheduler has recovered
145 return true;
146 }
147
148 auto detectionThresholdString =
149 snap::utils::time::Duration<std::chrono::steady_clock>(detectionThreshold).toString();
150 if (moduleName.isEmpty()) {
151 message = fmt::format("Detected unattributed ANR after {}", detectionThresholdString);
152 } else {
153 message = fmt::format("Detected ANR in '{}' after {}", moduleName, detectionThresholdString);
154 }
155
156 if (stacktraces.empty()) {
157 message += " but unable to capture stack traces.";
158 }
159
160 // getCurrentModuleLoadInfo() reads saved native state, not JS, so it is safe to call while the
161 // ANR has the JS thread stuck.
162 auto moduleLoadInfo = taskScheduler.getCurrentModuleLoadInfo();
163 if (!moduleLoadInfo.empty()) {
164 message += " [module-load: " + moduleLoadInfo + "]";
165 }
166
167 VALDI_ERROR(*_logger, "{}", message);
168 for (const auto& stacktrace : stacktraces) {
169 if (stacktrace.getStatus() == JavaScriptCapturedStacktrace::Status::RUNNING) {
170 VALDI_ERROR(*_logger, "ANR Stacktrace:\n{}", stacktrace.getStackTrace());
171 }
172 }
173
174 Ref<Metrics> metrics;
175 Ref<IJavaScriptANRDetectorListener> listener;
176 {
177 std::lock_guard<Mutex> lock(_mutex);
178 metrics = _metrics;
179 listener = _listener;
180 }
181
182 if (metrics != nullptr) {
183 if (moduleName.isEmpty()) {
184 metrics->emitANR();
185 } else {
186 metrics->emitANR(moduleName);
187 }
188 }

Callers

nothing calls this directly

Calls 14

hasRunningStacktraceFunction · 0.85
JavaScriptANRClass · 0.85
getStatusMethod · 0.80
emitANRMethod · 0.80
withAttributionMethod · 0.80
loadMethod · 0.65
toStringMethod · 0.65
getStackTraceMethod · 0.65
captureStackTracesMethod · 0.45
emptyMethod · 0.45
getContextMethod · 0.45
getPathMethod · 0.45

Tested by

no test coverage detected