You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor: replace assert() with NS_CHECK/NS_DCHECK
assert() never runs in a build we ship. assembleRelease maps to the
RelWithDebInfo CMake config, whose stock CMAKE_CXX_FLAGS_RELWITHDEBINFO
carries -DNDEBUG, and CMakeLists appends -O3 to that variable rather than
replacing it, so nothing removes the define. All 123 first-party asserts were
therefore diagnostics that existed only in debug and test runs -- the two
places the invariants were least likely to be violated.
Two macros replace them, both in NativeScriptAssert.h:
NS_CHECK evaluates and aborts in every configuration.
NS_DCHECK evaluates and aborts in debug builds only.
61 sites become NS_CHECK: the JNIEnv/JavaVM handles and the jclass, jmethodID
and jfieldID lookups resolved once during runtime initialisation from fixed
class names, plus the per-isolate V8StringConstants block. Every one of them
is used unconditionally a statement or two later, so a null there is undefined
behaviour today and surfaces as a tombstone pointing at whatever ran next.
JEnv::GetMethodID and friends already call CheckForJavaException, so these
fire only when a lookup returns null with no pending Java exception; they are
backstops, not the primary error path.
The remaining 62 sites keep debug-only semantics as NS_DCHECK. Notably
MethodCache and FieldAccessor check the result of JEnv::FindClass, which
deliberately returns nullptr with a pending Java exception for a class that is
genuinely missing and lets the caller raise a NativeScriptException. Aborting
there would turn a handled, recoverable path into a crash.
A failed NS_CHECK records the expression and source location through
CrashBreadcrumbs::RecordFatal and logs it at ANDROID_LOG_FATAL, which claims
the bionic abort message slot, so the check names itself in the tombstone and
in the breadcrumb file the next launch reports. RecordFatal takes no lock and
writes a buffer the signal handler already knows how to emit, so it is safe on
a thread that is aborting from under one of the runtime's own locks.
NS_DCHECK still compiles its expression when NDEBUG is defined, in a branch
that is never taken, so an expression that stops making sense is a build
failure instead of something only a debug build notices. It follows that the
expression must stay free of side effects, exactly as with assert().
0 commit comments