Skip to content

Commit 79feec0

Browse files
committed
Add comprehensive debug logging and memory barriers for macOS CI primitive data bug
This commit addresses the macOS CI-specific primitive data bug where setPrimitiveDataInt() succeeds but doesPrimitiveDataExist() immediately returns false. Research indicates this is likely thread_local storage issues in macOS CI environments.
1 parent d263023 commit 79feec0

2 files changed

Lines changed: 54 additions & 1 deletion

File tree

native/src/pyhelios_wrapper_common.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@
44
#include "../include/pyhelios_wrapper_common.h"
55
#include <string>
66
#include <exception>
7+
#include <cstdio>
78

89
// Global error state for thread-safe error handling - matches PyHelios error codes
910
static thread_local std::string last_error_message;
1011
static thread_local int last_error_code = PYHELIOS_SUCCESS;
1112

1213
// Helper function to set error state with PyHelios error codes
1314
void setError(int error_code, const std::string& message) {
15+
// Debug logging for macOS CI thread_local investigation
16+
fprintf(stderr, "[DEBUG-THREAD_LOCAL] setError called: code=%d, message=%s\n", error_code, message.c_str());
17+
fprintf(stderr, "[DEBUG-THREAD_LOCAL] Previous error state: code=%d\n", last_error_code);
18+
1419
last_error_code = error_code;
1520
last_error_message = message;
21+
22+
fprintf(stderr, "[DEBUG-THREAD_LOCAL] Error state updated: code=%d\n", last_error_code);
1623
}
1724

1825
extern "C" {
@@ -22,6 +29,7 @@ extern "C" {
2229
//=============================================================================
2330

2431
int getLastErrorCode() {
32+
fprintf(stderr, "[DEBUG-THREAD_LOCAL] getLastErrorCode() returning: %d\n", last_error_code);
2533
return last_error_code;
2634
}
2735

@@ -30,8 +38,10 @@ extern "C" {
3038
}
3139

3240
void clearError() {
41+
fprintf(stderr, "[DEBUG-THREAD_LOCAL] clearError() called, previous code: %d\n", last_error_code);
3342
last_error_code = PYHELIOS_SUCCESS;
3443
last_error_message.clear();
44+
fprintf(stderr, "[DEBUG-THREAD_LOCAL] clearError() completed, new code: %d\n", last_error_code);
3545
}
3646

3747
} //extern "C"

native/src/pyhelios_wrapper_context.cpp

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include <string>
88
#include <exception>
99
#include <cstring>
10+
#include <cstdio>
11+
#include <atomic>
1012

1113
extern "C" {
1214
// Context management - core functionality required by PyHelios
@@ -1476,21 +1478,43 @@ extern "C" {
14761478
void setPrimitiveDataInt(helios::Context* context, unsigned int uuid, const char* label, int value) {
14771479
// Clear error state before any operation to prevent contamination from previous calls
14781480
clearError();
1481+
1482+
// Debug logging for macOS CI investigation
1483+
fprintf(stderr, "[DEBUG-MACOS] setPrimitiveDataInt: uuid=%u, label=%s, value=%d\n", uuid, label, value);
1484+
fprintf(stderr, "[DEBUG-MACOS] Initial error state: code=%d\n", getLastErrorCode());
1485+
14791486
try {
14801487
if (!context) {
14811488
setError(PYHELIOS_ERROR_INVALID_PARAMETER, "Context pointer is null");
1489+
fprintf(stderr, "[DEBUG-MACOS] ERROR: Context pointer is null\n");
14821490
return;
14831491
}
14841492
if (!label) {
14851493
setError(PYHELIOS_ERROR_INVALID_PARAMETER, "Label is null");
1494+
fprintf(stderr, "[DEBUG-MACOS] ERROR: Label is null\n");
14861495
return;
14871496
}
1497+
1498+
fprintf(stderr, "[DEBUG-MACOS] About to call context->setPrimitiveData()\n");
14881499
context->setPrimitiveData(uuid, label, value);
1500+
1501+
// Memory barrier to ensure data write completion before verification
1502+
std::atomic_thread_fence(std::memory_order_seq_cst);
1503+
fprintf(stderr, "[DEBUG-MACOS] context->setPrimitiveData() completed successfully with memory barrier\n");
1504+
1505+
// Immediate verification to debug thread_local storage issue
1506+
bool exists_immediately = context->doesPrimitiveDataExist(uuid, label);
1507+
fprintf(stderr, "[DEBUG-MACOS] Immediate verification: exists=%s\n", exists_immediately ? "true" : "false");
1508+
14891509
} catch (const std::exception& e) {
14901510
setError(PYHELIOS_ERROR_RUNTIME, std::string("ERROR (Context::setPrimitiveData): ") + e.what());
1511+
fprintf(stderr, "[DEBUG-MACOS] Exception caught: %s\n", e.what());
14911512
} catch (...) {
14921513
setError(PYHELIOS_ERROR_UNKNOWN, "ERROR (Context::setPrimitiveData): Unknown error setting primitive data int.");
1514+
fprintf(stderr, "[DEBUG-MACOS] Unknown exception caught\n");
14931515
}
1516+
1517+
fprintf(stderr, "[DEBUG-MACOS] Final error state: code=%d\n", getLastErrorCode());
14941518
}
14951519

14961520
void setPrimitiveDataString(helios::Context* context, unsigned int uuid, const char* label, const char* value) {
@@ -1595,23 +1619,42 @@ extern "C" {
15951619
bool doesPrimitiveDataExist(helios::Context* context, unsigned int uuid, const char* label) {
15961620
// Clear error state before any operation to prevent contamination from previous calls
15971621
clearError();
1622+
1623+
// Debug logging for macOS CI investigation
1624+
fprintf(stderr, "[DEBUG-MACOS] doesPrimitiveDataExist: uuid=%u, label=%s\n", uuid, label);
1625+
fprintf(stderr, "[DEBUG-MACOS] Initial error state: code=%d\n", getLastErrorCode());
1626+
15981627
try {
15991628
if (!context) {
16001629
setError(PYHELIOS_ERROR_INVALID_PARAMETER, "Context pointer is null");
1630+
fprintf(stderr, "[DEBUG-MACOS] ERROR: Context pointer is null\n");
16011631
return false;
16021632
}
16031633
if (!label) {
16041634
setError(PYHELIOS_ERROR_INVALID_PARAMETER, "Label is null");
1635+
fprintf(stderr, "[DEBUG-MACOS] ERROR: Label is null\n");
16051636
return false;
16061637
}
1607-
return context->doesPrimitiveDataExist(uuid, label);
1638+
1639+
fprintf(stderr, "[DEBUG-MACOS] About to call context->doesPrimitiveDataExist()\n");
1640+
1641+
// Memory barrier to ensure any pending writes are visible before reading
1642+
std::atomic_thread_fence(std::memory_order_acquire);
1643+
bool result = context->doesPrimitiveDataExist(uuid, label);
1644+
fprintf(stderr, "[DEBUG-MACOS] context->doesPrimitiveDataExist() returned: %s (with memory barrier)\n", result ? "true" : "false");
1645+
1646+
return result;
16081647
} catch (const std::exception& e) {
16091648
setError(PYHELIOS_ERROR_RUNTIME, std::string("ERROR (Context::doesPrimitiveDataExist): ") + e.what());
1649+
fprintf(stderr, "[DEBUG-MACOS] Exception caught: %s\n", e.what());
16101650
return false;
16111651
} catch (...) {
16121652
setError(PYHELIOS_ERROR_UNKNOWN, "ERROR (Context::doesPrimitiveDataExist): Unknown error checking primitive data existence.");
1653+
fprintf(stderr, "[DEBUG-MACOS] Unknown exception caught\n");
16131654
return false;
16141655
}
1656+
1657+
fprintf(stderr, "[DEBUG-MACOS] Final error state: code=%d\n", getLastErrorCode());
16151658
}
16161659

16171660
void setPrimitiveDataVec3(helios::Context* context, unsigned int uuid, const char* label, float x, float y, float z) {

0 commit comments

Comments
 (0)