Summary

This PR addresses the remaining crash issues in GitHub issue #7478 where closing multiple profiles simultaneously could cause crashes due to Qt widgets being accessed during destruction.

Problem Description

When rapidly closing multiple profiles (e.g., using Alt+W to close 16 profiles quickly), Mudlet would crash with a stack trace pointing to:

  • QTextLayout::preeditAreaText()
  • TMainConsole::printOnDisplay() at line 1182
  • Socket disconnection handling in cTelnet::slot_socketDisconnected()

Root Cause

The crash occurred due to a race condition during widget destruction:

  1. User rapidly closes profiles → Host::closeChildren() called → mIsClosingDown = true
  2. Socket disconnection triggers cTelnet::slot_socketDisconnected()postData()TMainConsole::printOnDisplay()
  3. Code attempts to call mpLineEdit_networkLatency->setText()
  4. CRASH: The QLineEdit pointer exists but its internal QTextLayout is already destroyed
  5. setText() tries to access destroyed memory → segmentation fault

The issue was that null pointer checks alone are insufficient - Qt widgets can have valid pointers while their internal components are destroyed.

Solution Approach

Instead of masking the problem with exception handling, this fix prevents unsafe widget access by using Qt’s built-in widget lifecycle indicators.

TMainConsole.cpp

// Before (vulnerable):
if (mpLineEdit_networkLatency && !mpHost->isClosingDown()) {
mpLineEdit_networkLatency->setText(...); // CRASH - widget internals destroyed
}
// After (safe):
if (mpLineEdit_networkLatency && !mpHost->isClosingDown()) {
QWidget* parentWidget = mpLineEdit_networkLatency->parentWidget();
if (parentWidget && mpLineEdit_networkLatency->isVisible()) {
mpLineEdit_networkLatency->setText(...); // SAFE - widget fully intact
}
}

ctelnet.cpp

// Before (vulnerable):
mpHost->mpConsole->printOnDisplay(mMudData, true); // Could crash
// After (safe):
QWidget* parentWidget = mpHost->mpConsole->parentWidget();
if (!parentWidget || !mpHost->mpConsole->isVisible()) {
return; // Skip if console is being destroyed
}
mpHost->mpConsole->printOnDisplay(mMudData, true); // Safe to proceed

Why This Works

Qt destroys widgets in a specific order:

  1. First: Remove from parent hierarchy (parentWidget() → null)
  2. Second: Set invisible (isVisible() → false)
  3. Last: Destroy internal components (where crashes occurred)

By checking both parentWidget() and isVisible(), we can reliably detect when a widget is in the destruction process and avoid accessing it entirely.

Related Issues

  • Fixes #7478
  • Builds upon the improvements made in #7461

/claim #7478.

Claim

Total prize pool $100
Total paid $0
Status Pending
Submitted August 17, 2025
Last updated August 17, 2025

Contributors

RI

Rishi Mondal

@MAVRICK-1

100%

Sponsors

MU

Mudlet

@Mudlet

$100