v0.7.15 - Fixed race condition in subscription management causing intermittent core dumps and format truncation warning
This commit is contained in:
@@ -174,7 +174,7 @@
|
||||
|
||||
|
||||
<!-- DATABASE STATISTICS Section -->
|
||||
<div class="section">
|
||||
<div class="section" id="databaseStatisticsSection" style="display: none;">
|
||||
<div class="section-header">
|
||||
<h2>DATABASE STATISTICS</h2>
|
||||
</div>
|
||||
|
||||
@@ -607,11 +607,13 @@
|
||||
function updateAdminSectionsVisibility() {
|
||||
const divConfig = document.getElementById('div_config');
|
||||
const authRulesSection = document.getElementById('authRulesSection');
|
||||
const databaseStatisticsSection = document.getElementById('databaseStatisticsSection');
|
||||
const nip17DMSection = document.getElementById('nip17DMSection');
|
||||
const shouldShow = isLoggedIn && isRelayConnected;
|
||||
|
||||
if (divConfig) divConfig.style.display = shouldShow ? 'block' : 'none';
|
||||
if (authRulesSection) authRulesSection.style.display = shouldShow ? 'block' : 'none';
|
||||
if (databaseStatisticsSection) databaseStatisticsSection.style.display = shouldShow ? 'block' : 'none';
|
||||
if (nip17DMSection) nip17DMSection.style.display = shouldShow ? 'block' : 'none';
|
||||
}
|
||||
|
||||
@@ -2131,7 +2133,7 @@
|
||||
const originalShowMainInterface = showMainInterface;
|
||||
showMainInterface = function () {
|
||||
originalShowMainInterface();
|
||||
showAuthRulesSection();
|
||||
// Removed showAuthRulesSection() call - visibility now handled by updateAdminSectionsVisibility()
|
||||
};
|
||||
|
||||
// Auth rules event handlers
|
||||
@@ -3532,6 +3534,9 @@
|
||||
// Initialize login/logout button state
|
||||
updateLoginLogoutButton();
|
||||
|
||||
// Ensure admin sections are hidden by default on page load
|
||||
updateAdminSectionsVisibility();
|
||||
|
||||
setTimeout(() => {
|
||||
initializeApp();
|
||||
// Enhance SimplePool for testing after initialization
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# C-Relay Static Binary Deployment Script
|
||||
# Deploys build/c_relay_static_x86_64 to server via sshlt
|
||||
# Usage: ./deploy_static.sh [--debug-level=N] [-d=N]
|
||||
# Deploys build/c_relay_static_x86_64 to server via ssh
|
||||
|
||||
set -e
|
||||
|
||||
@@ -11,44 +10,6 @@ LOCAL_BINARY="build/c_relay_static_x86_64"
|
||||
REMOTE_BINARY_PATH="/usr/local/bin/c_relay/c_relay"
|
||||
SERVICE_NAME="c-relay"
|
||||
|
||||
# Default debug level
|
||||
DEBUG_LEVEL=0
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--debug-level=*)
|
||||
DEBUG_LEVEL="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
-d=*)
|
||||
DEBUG_LEVEL="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
--debug-level)
|
||||
DEBUG_LEVEL="$2"
|
||||
shift 2
|
||||
;;
|
||||
-d)
|
||||
DEBUG_LEVEL="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
echo "Usage: $0 [--debug-level=N] [-d=N]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate debug level
|
||||
if ! [[ "$DEBUG_LEVEL" =~ ^[0-5]$ ]]; then
|
||||
echo "Error: Debug level must be 0-5, got: $DEBUG_LEVEL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Deploying with debug level: $DEBUG_LEVEL"
|
||||
|
||||
# Create backup
|
||||
ssh ubuntu@laantungir.com "sudo cp '$REMOTE_BINARY_PATH' '${REMOTE_BINARY_PATH}.backup.$(date +%Y%m%d_%H%M%S)'" 2>/dev/null || true
|
||||
|
||||
@@ -60,9 +21,6 @@ ssh ubuntu@laantungir.com "sudo mv '/tmp/c_relay.tmp' '$REMOTE_BINARY_PATH'"
|
||||
ssh ubuntu@laantungir.com "sudo chown c-relay:c-relay '$REMOTE_BINARY_PATH'"
|
||||
ssh ubuntu@laantungir.com "sudo chmod +x '$REMOTE_BINARY_PATH'"
|
||||
|
||||
# Update systemd service environment variable
|
||||
ssh ubuntu@laantungir.com "sudo sed -i 's/Environment=DEBUG_LEVEL=.*/Environment=DEBUG_LEVEL=$DEBUG_LEVEL/' /etc/systemd/system/c-relay.service"
|
||||
|
||||
# Reload systemd and restart service
|
||||
ssh ubuntu@laantungir.com "sudo systemctl daemon-reload"
|
||||
ssh ubuntu@laantungir.com "sudo systemctl restart '$SERVICE_NAME'"
|
||||
|
||||
40
notes.txt
Normal file
40
notes.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
Task Completed
|
||||
Perfect! The core dump limit is now set correctly. You can see both:
|
||||
|
||||
LimitCORE=infinity
|
||||
LimitCORESoft=infinity
|
||||
What happens next:
|
||||
The relay is now configured to generate core dumps when it crashes
|
||||
Wait for the next crash to occur (based on your logs, it seems to happen intermittently)
|
||||
When it crashes, the core dump will be automatically captured by systemd
|
||||
After the next crash, analyze it:
|
||||
# List all core dumps (most recent first)
|
||||
sudo coredumpctl list
|
||||
|
||||
# View info about the most recent c-relay crash
|
||||
sudo coredumpctl info c-relay
|
||||
|
||||
# Load the core dump in gdb for detailed analysis
|
||||
sudo coredumpctl gdb c-relay
|
||||
|
||||
Inside gdb, run these commands:
|
||||
(gdb) bt full # Full backtrace with all variables
|
||||
(gdb) info threads # Show all threads
|
||||
(gdb) thread apply all bt # Backtrace for all threads
|
||||
(gdb) frame 0 # Go to crash frame
|
||||
(gdb) info locals # Show local variables
|
||||
(gdb) list # Show source code around crash
|
||||
|
||||
The backtrace will show you exactly which line of code caused the segmentation fault and the state of all variables at that moment, which should pinpoint whether it's the subscription management issue, buffer overflow, or something else.
|
||||
|
||||
You're all set up now - just wait for the next crash and then run the coredumpctl commands to analyze it.
|
||||
|
||||
|
||||
--------------------------
|
||||
|
||||
|
||||
Even simpler: Use this one-liner
|
||||
# Start relay and immediately attach gdb
|
||||
cd /usr/local/bin/c_relay
|
||||
sudo -u c-relay ./c_relay --debug-level=5 & sleep 2 && sudo gdb -p $(pgrep c_relay)
|
||||
File diff suppressed because one or more lines are too long
@@ -622,7 +622,8 @@ int broadcast_event_to_subscriptions(cJSON* event) {
|
||||
subscription_t* update_sub = g_subscription_manager.active_subscriptions;
|
||||
while (update_sub) {
|
||||
if (update_sub->wsi == current_temp->wsi &&
|
||||
strcmp(update_sub->id, current_temp->id) == 0) {
|
||||
strcmp(update_sub->id, current_temp->id) == 0 &&
|
||||
update_sub->active) { // Add active check to prevent use-after-free
|
||||
update_sub->events_sent++;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -516,8 +516,28 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
|
||||
if (event_kind == 23456) {
|
||||
if (admin_result != 0) {
|
||||
char error_result_msg[512];
|
||||
if (admin_error && strlen(admin_error) > 0) {
|
||||
// Safely truncate admin_error if too long
|
||||
size_t max_error_len = sizeof(error_result_msg) - 50; // Leave room for prefix
|
||||
size_t error_len = strlen(admin_error);
|
||||
if (error_len > max_error_len) {
|
||||
error_len = max_error_len;
|
||||
}
|
||||
char truncated_error[512];
|
||||
memcpy(truncated_error, admin_error, error_len);
|
||||
truncated_error[error_len] = '\0';
|
||||
|
||||
// Use a safer approach to avoid truncation warning
|
||||
size_t prefix_len = snprintf(error_result_msg, sizeof(error_result_msg),
|
||||
"ERROR: Kind %d event processing failed: ", event_kind);
|
||||
if (prefix_len < sizeof(error_result_msg)) {
|
||||
size_t remaining = sizeof(error_result_msg) - prefix_len;
|
||||
strncat(error_result_msg, truncated_error, remaining - 1);
|
||||
}
|
||||
} else {
|
||||
snprintf(error_result_msg, sizeof(error_result_msg),
|
||||
"ERROR: Kind %d event processing failed: %s", event_kind, admin_error);
|
||||
"ERROR: Kind %d event processing failed", event_kind);
|
||||
}
|
||||
DEBUG_ERROR(error_result_msg);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user