Debugging Guide: mycroft-gui-qt6
March 12, 2026 · View on GitHub
How to debug and troubleshoot mycroft-gui-qt6
Debugging Modes
Debug Build
Build with debug symbols for better debugging:
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON
make clean && make -j$(nproc)
This enables:
- ✅ Full debug symbols (file:line information)
- ✅ Assertions and Q_ASSERT checks
- ✅ Slower performance (acceptable for development)
Command-Line Debugging
Enable Debug Output
# Very verbose output
mycroft-gui-app --log-level debug 2>&1 | tee debug.log
# Just errors
mycroft-gui-app --log-level error
# Or set environment variable
QT_LOGGING_RULES="*.debug=true" mycroft-gui-app
Debug output shows:
- Connection status
- Message routing
- Signal emissions
- QML loading
- Session data changes
Print Debugging (qDebug)
Add temporary debug output:
// mycroftcontroller.cpp
void MycroftController::onWebSocketConnected() {
qDebug() << "WebSocket connected!";
qDebug() << "Server:" << m_socket.peerName();
qDebug() << "Port:" << m_socket.peerPort();
// Your actual code
m_connected = true;
}
Run with output:
mycroft-gui-app 2>&1 | grep "WebSocket connected"
QML Debugging
Debug QML with:
// In any QML file
import QtQuick
Item {
Component.onCompleted: {
console.log("Item loaded:", this)
console.log("Width:", width, "Height:", height)
}
onWidthChanged: console.log("Width changed to:", width)
}
Output appears in console/log when running with:
mycroft-gui-app --log-level debug
Using Qt Creator IDE
Setup Qt Creator
# Install Qt Creator (if not already installed)
sudo apt install qtcreator # Ubuntu/Debian
sudo dnf install qt-creator # Fedora
# Open Qt Creator
qtcreator &
Open and Debug Project
-
File → Open File or Project
- Select
mycroft-gui-qt6/CMakeLists.txt
- Select
-
Configure
- Select build kit (GCC/Clang)
- Select build directory
-
Build
- Build → Build Project
-
Debug
- Debug → Start Debugging
- Or press F5
Set Breakpoints
- Click in line number margin to set breakpoint (red dot appears)
- Run with Debug (F5)
- Execution stops at breakpoint
- Inspect variables in Variables pane
- Step with F10 (line) or F11 (into function)
Watch Variables
In Debugger → Locals & Expressions:
- Right-click variable
- "Add to Watch"
- Variable updates shown as you step
Example Debugging Session
File: import/mycroftcontroller.cpp
Line: onWebSocketConnected()
1. Set breakpoint on m_connected = true;
2. Start mycroft-gui-app with debugger
3. When connection made, breakpoint hit
4. Inspect m_socket.peerName() in Variables pane
5. Step through connection code
6. Check m_isConnected value
GDB Command-Line Debugging
For shell-based debugging (remote servers, etc.):
# Build with debug symbols
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug
make clean && make
# Start app under gdb
gdb ./mycroft-gui-app
# In gdb prompt:
(gdb) break MycroftController::onWebSocketConnected
(gdb) run
# ... app runs until breakpoint hits ...
(gdb) print m_socket.peerName()
(gdb) step
(gdb) next
(gdb) continue
(gdb) quit
Common GDB commands:
break <function> # Set breakpoint
run # Start program
continue (c) # Resume after breakpoint
step (s) # Step into function
next (n) # Execute line, don't step in
print <var> # Print variable value
backtrace (bt) # Show call stack
up/down # Navigate call stack
quit (q) # Exit debugger
Memory Debugging
Detect Memory Leaks
Build with AddressSanitizer:
cd build
cmake .. -DCMAKE_CXX_FLAGS="-fsanitize=address" -DCMAKE_BUILD_TYPE=Debug
make clean && make -j$(nproc)
# Run
./mycroft-gui-app
# Or run tests
make test VERBOSE=1
Output shows:
=================================================================
==12345==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 256 byte(s) in 1 object(s) allocated from:
#0 0x7ffff7a6d099 in operator new (/lib/libc.so.6+...)
#1 0x5555557a1b3c in MycroftController::connect() ...
Detect Use-After-Free
Same AddressSanitizer build catches:
==12345==ERROR: AddressSanitizer: heap-use-after-free on address
Valgrind (detailed memory analysis)
# Install valgrind
sudo apt install valgrind # Ubuntu/Debian
# Run with valgrind
valgrind --leak-check=full \
--show-leak-kinds=all \
--track-origins=yes \
./mycroft-gui-app
# For tests
valgrind --leak-check=full ./autotests/message_routing_test
Performance Debugging
Profile with Qt Creator
- Analyze → QML Profiler
- Start program
- Observe frame rate, memory usage
- Identify hot spots
Profile with perf (Linux)
# Install
sudo apt install linux-tools
# Record
perf record -g ./mycroft-gui-app
# Run your scenario, then Ctrl+C
# Analyze
perf report
# Or generate flamegraph
perf script | stackcollapse-perf.pl | flamegraph.pl > flamegraph.svg
Check Memory Usage
# While running mycroft-gui-app in another terminal
watch -n 1 'ps aux | grep mycroft-gui'
# Check process details
cat /proc/$(pidof mycroft-gui-app)/status | grep VmRSS
# Real-time monitoring
htop
# Search for mycroft-gui-app (press f)
# Check VIRT and RES columns
Network Debugging
Monitor WebSocket Traffic
# Install Wireshark
sudo apt install wireshark
# Capture traffic
sudo wireshark &
# Or use tcpdump
sudo tcpdump -i lo -A 'tcp port 18181'
Check Port Connectivity
# Is port 18181 listening?
netstat -tlnp | grep 18181
# Or with ss
ss -tlnp | grep 18181
# Try connecting
nc -zv localhost 18181
# Or with curl (if WebSocket endpoint supports HTTP)
curl -v ws://localhost:18181
Mock WebSocket Server
For testing without ovos-gui:
# test_websocket_server.py
import asyncio
import json
from websockets import serve
async def echo(websocket, path):
async for message in websocket:
data = json.loads(message)
print(f"Received: {data}")
# Send back session data
response = {
"type": "gui.page.show",
"namespace": "test",
"data": {"message": "Hello from test server"}
}
await websocket.send(json.dumps(response))
async def main():
async with serve(echo, "localhost", 18181):
print("Test server on ws://localhost:18181")
await asyncio.Future()
asyncio.run(main())
Run with:
python3 test_websocket_server.py
# In another terminal
mycroft-gui-app
QML Debugging
QML Profiler
In Qt Creator:
- Analyze → QML Profiler
- Click Start button
- Run mycroft-gui-app
- Observe rendering, signal emission, memory allocation
QML Language Server (Qt Creator Integration)
Automatic when opening .qml files:
- Syntax highlighting
- Auto-completion
- Go to definition (Ctrl+click)
- Find references (Ctrl+Shift+U)
Enable QML Debugging
Run with QML debugging enabled:
mycroft-gui-app --qmljsdebugger=port:3768,block
Then in Qt Creator:
- Debug → Attach to QML Debugger
- Port: 3768
Common Issues & Debugging
Issue: "Cannot connect to ovos-gui"
Debug steps:
# 1. Check ovos-gui is running
systemctl status ovos-gui
# 2. Check port is listening
netstat -tlnp | grep 18181
# 3. Check logs
mycroft-gui-app --log-level debug 2>&1 | grep -i connect
# 4. Check firewall
sudo ufw status
sudo ufw allow 18181
# 5. Check mycroft.conf
cat ~/.config/mycroft/mycroft.conf | grep -A 3 gui_websocket
Solution:
- Start ovos-gui first
- Verify port 18181 is in mycroft.conf
- Check firewall isn't blocking
Issue: "QML module not found"
Debug steps:
# 1. Check QML import path
echo $QML_IMPORT_PATH
# 2. Check library is installed
pkg-config --modversion mycroft-gui-qt6
# 3. Check library path
ldd /usr/local/lib/libmycroft-gui-qt6.so | grep -i kirigami
# 4. Verify QML plugin
ls -la /usr/local/lib/qt6/qml/Mycroft/
Solution:
export QML_IMPORT_PATH=/usr/local/lib/qt6/qml:$QML_IMPORT_PATH
mycroft-gui-app
Issue: "Qt plugin error"
Debug steps:
# 1. Check Qt plugin path
echo $QT_PLUGIN_PATH
# 2. Check plugins exist
ls /usr/lib/qt6/plugins/platforms/
# 3. Try with explicit path
export QT_PLUGIN_PATH=/usr/lib/qt6/plugins:$QT_PLUGIN_PATH
mycroft-gui-app
Solution:
- Set QT_PLUGIN_PATH before running
- Add to ~/.bashrc for persistence
Issue: Segmentation Fault
Debug steps:
# 1. Run with gdb
gdb ./mycroft-gui-app
(gdb) run
# ... crash happens ...
(gdb) backtrace
# Shows call stack
# 2. Or use AddressSanitizer
cmake .. -DCMAKE_CXX_FLAGS="-fsanitize=address"
make && ./mycroft-gui-app
Solution:
- Look at backtrace to find crash location
- Check NULL pointer dereference
- Check array bounds
- Use memory debugger
Logging Best Practices
For Users (Production)
Minimal logging:
// Only log critical errors
qWarning() << "Failed to connect:" << errorString;
For Developers (Development)
Detailed logging:
qDebug() << "MycroftController::onWebSocketConnected()";
qDebug() << " Server:" << m_socket.peerName();
qDebug() << " Port:" << m_socket.peerPort();
qDebug() << " Connected:" << m_connected;
Conditional Logging
#ifdef QT_DEBUG
qDebug() << "Detailed debug info";
#endif
// Or at runtime
if (qEnvironmentVariableIsSet("DEBUG_MYCROFT")) {
qDebug() << "Debug mode enabled";
}
Enable with:
DEBUG_MYCROFT=1 mycroft-gui-app
Remote Debugging
Debug on Different Machine
# On target machine
gdbserver :1234 ./mycroft-gui-app
# On development machine
gdb ./mycroft-gui-app
(gdb) target remote <target-ip>:1234
(gdb) break MycroftController::connect
(gdb) continue
Debug in Container
# Build debug image
docker build -f Dockerfile.debug -t mycroft-gui-qt6-debug .
# Run with debugging enabled
docker run -it -p 3768:3768 mycroft-gui-qt6-debug
# Connect with Qt Creator
# Debug → Attach to QML Debugger
# Port: 3768
Debugging Checklist
Before asking for help:
- Run with
--log-level debug - Check recent log file in
~/.cache/ - Verify ovos-gui is running
- Verify port 18181 is listening
- Check mycroft.conf configuration
- Run test suite (
make test) - Check for memory leaks (AddressSanitizer)
- Try clean rebuild (
make clean && make) - Update environment variables (QML_IMPORT_PATH, etc.)
Next Steps
- Read TESTING.md: How to write and run tests
- Read CONTRIBUTING.md: Guidelines for bug reports
- Check CODE_GUIDE.md: Understand the code structure
Happy debugging! 🐛