chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
//
|
||||
// Created by agibsonccc on 5/11/23.
|
||||
//
|
||||
#include <system/op_boilerplate.h>
|
||||
#include <execution/LaunchContext.h>
|
||||
#include <exceptions/backward.hpp>
|
||||
|
||||
using namespace backward;
|
||||
|
||||
// Helper function to safely check if LaunchContext is initialized
|
||||
// Returns true if it's safe to use LaunchContext, false otherwise
|
||||
static bool isLaunchContextReady() {
|
||||
// During early initialization (e.g., static initializers, before main()),
|
||||
// LaunchContext may not be initialized yet. Attempting to use it can cause
|
||||
// crashes. This function provides a safe check.
|
||||
|
||||
// DON'T try to call LaunchContext::defaultContext() here!
|
||||
// Even calling it can trigger crashes during early initialization.
|
||||
// The safer approach is to just return false during exception handling
|
||||
// and let fprintf write to stderr instead.
|
||||
|
||||
// We can't safely determine if LaunchContext is ready without potentially
|
||||
// triggering the same initialization issues we're trying to avoid.
|
||||
// So we conservatively return false and use fprintf for error reporting.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Safe helper function for setting error context in exception handlers
|
||||
// This should be used in ALL catch blocks in JNI code instead of directly
|
||||
// calling LaunchContext::defaultContext()->errorReference()
|
||||
void safeSetErrorContext(int errorCode, const char* errorMessage) {
|
||||
if (isLaunchContextReady()) {
|
||||
#ifdef __cpp_exceptions
|
||||
try {
|
||||
sd::LaunchContext::defaultContext()->errorReference()->setErrorCode(errorCode);
|
||||
sd::LaunchContext::defaultContext()->errorReference()->setErrorMessage(errorMessage);
|
||||
} catch (...) {
|
||||
// If setting error context fails, just log to stderr
|
||||
// Don't let this cause another exception
|
||||
fprintf(stderr, "Warning: Failed to set error context (code=%d): %s\n", errorCode, errorMessage);
|
||||
}
|
||||
#else
|
||||
// Exceptions disabled - direct call without try/catch
|
||||
sd::LaunchContext::defaultContext()->errorReference()->setErrorCode(errorCode);
|
||||
sd::LaunchContext::defaultContext()->errorReference()->setErrorMessage(errorMessage);
|
||||
#endif
|
||||
} else {
|
||||
// LaunchContext not ready - just log to stderr
|
||||
// This is normal during early JVM initialization
|
||||
fprintf(stderr, "Error (code=%d) during early initialization: %s\n", errorCode, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SD_GCC_FUNCTRACE)
|
||||
void throwException(const char* exceptionMessage) {
|
||||
#ifndef __CUDA_CC__
|
||||
// Diagnostic: verify this code path executes
|
||||
fprintf(stderr, "\n[throwException] SD_GCC_FUNCTRACE build - capturing stack trace\n");
|
||||
fflush(stderr);
|
||||
|
||||
// Print exception message first
|
||||
fprintf(stderr, "=== EXCEPTION: %s ===\n", exceptionMessage);
|
||||
fflush(stderr);
|
||||
|
||||
// Capture and print stack trace
|
||||
StackTrace st;
|
||||
st.load_here(64);
|
||||
|
||||
if (st.size() > 0) {
|
||||
fprintf(stderr, "Stack trace (%zu frames):\n", st.size());
|
||||
fflush(stderr);
|
||||
Printer p;
|
||||
p.snippet = false;
|
||||
p.color_mode = ColorMode::never;
|
||||
p.address = true;
|
||||
p.object = true;
|
||||
p.print(st, stderr);
|
||||
fflush(stderr);
|
||||
} else {
|
||||
fprintf(stderr, "Stack trace: Unable to capture (0 frames captured)\n");
|
||||
fprintf(stderr, "This may indicate missing unwind tables or debug info\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
fprintf(stderr, "=== END STACK TRACE ===\n\n");
|
||||
fflush(stderr);
|
||||
#endif
|
||||
|
||||
// Set error context for Java to retrieve using safe wrapper
|
||||
// CRITICAL: Don't directly call LaunchContext during exception handling
|
||||
// to avoid static initialization/destruction order issues
|
||||
safeSetErrorContext(1, exceptionMessage);
|
||||
|
||||
#ifdef __cpp_exceptions
|
||||
throw std::runtime_error(exceptionMessage);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
void throwException(const char* exceptionMessage) {
|
||||
// Diagnostic: verify this code path executes
|
||||
fprintf(stderr, "\n[throwException] Non-functrace build - no stack trace available\n");
|
||||
fprintf(stderr, "Exception: %s\n", exceptionMessage);
|
||||
fflush(stderr);
|
||||
|
||||
// Set error context for Java to retrieve using safe wrapper
|
||||
// CRITICAL: Don't directly call LaunchContext during exception handling
|
||||
// to avoid static initialization/destruction order issues
|
||||
safeSetErrorContext(1, exceptionMessage);
|
||||
|
||||
#ifdef __cpp_exceptions
|
||||
throw std::runtime_error(exceptionMessage);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user