fix: PyQt6 migration completion and crash fixes across frontend and NGHDL#521
Open
VaradhaCodes wants to merge 2 commits into
Open
fix: PyQt6 migration completion and crash fixes across frontend and NGHDL#521VaradhaCodes wants to merge 2 commits into
VaradhaCodes wants to merge 2 commits into
Conversation
…netlist lines Malformed SPICE component lines with fewer tokens than expected caused IndexError crashes when opening KiCad→Ngspice converter. Added len(words) guards on all five device branches (q, d, j, s, m) — short lines are silently skipped, consistent with existing try/except BaseException patterns. Triggered by SN55451B netlist where diode lines had only 2 tokens (D2 __D2).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
PR #498 migrated PyQt5 to PyQt6 and got merged. The stated testing was "main window and workspace initialization". That's it. No simulation, no KicadtoNgspice, no NGHDL, no model editor -- just the app opening.
As a result, most of the actual features were broken on the merged branch. This PR goes through them one by one. Every crash listed below was triggered by actually using the feature and testing it.
src/ngspiceSimulation/module is handled separately in the companion PR.Crashes fixed (in order of how bad they were)
1. NGHDL model upload hangs and never finishes
QProcess.start("make install")passes the full string as the program name in Qt6 -- the args need to be a separate list. Somake installwas silently hanging. On top of that,readAllStandardwas readingself.processinstead ofself.sender(), so if you tried twice in the same session it would read from the wrong process and crash.make installwas also being called immediately instead of waiting formaketo finish.Fixed:
start(prog, [args])split, signals connected beforestart(),make installsequenced viafinishedsignal, slot readsself.sender().nghdl/src/ngspice_ghdl.py2. NgVeri refresh button causes segfault
The
toggleQThread was callingoption.setStyleSheet()directly from the background thread. Touching Qt GUI objects from a non-main thread is undefined behaviour and causes random segfaults. Separately, the watchdogon_modifiedhandler was creating and callingQErrorMessagefrom watchdog's thread, same problem.Fixed:
pyqtSignal(str)bridge in toggle so style changes go through the main thread. Same for the modified dialog. Added propercloseEventto stop threads and observer on widget close.src/maker/Maker.py3. Simulation plot doesn't open after ngspice finishes
plotSimulationDatawas declared(self, exitCode, exitStatus)butQProcess.finishedemits(exitCode: int, exitStatus: QProcess.ExitStatus)-- the two args are in that order. The slot had them reversed, so it was receiving the enum as an int and vice versa. In PyQt6 the type checking is stricter so it fails silently.src/frontEnd/Application.py4. KicadtoNgspice has stale data from previous session
TrackWidgetstores everything at the class level (shared across instances). The reset at the start of each conversion only cleared 3 of the 14 attributes. So if you opened KicadtoNgspice, closed it, and opened it again for a different schematic, it would mix in subcircuit/model data from the previous run.Fixed: added
TrackWidget.reset()classmethod that resets all 14 attributes, called at the start of each conversion.src/kicadtoNgspice/TrackWidget.py,KicadtoNgspice.py5. KicadtoNgspice crashes on netlists with simple DC sources
words[3]was accessed directly without checkinglen(words). A plain DC source line doesn't have a 4th token, soIndexErrorwas crashing the entire window.src/kicadtoNgspice/Processing.py6. Analysis panel crashes loading saved simulations
root[x][y].textreturnsNonewhen an XML element is empty. This was passed directly tosetText()andfindText(), both of which crash onNone. AlsosetCurrentIndexwas called with -1 (whatfindTextreturns on no match), which resets the combo to blank.Added
or ""on all text reads andif index >= 0beforesetCurrentIndex.src/kicadtoNgspice/Analysis.py7. KicadtoNgspice crashes on empty unit string in conversion
scientificConversionaccessedstring_obj[0]without checking for empty string. Added early return.src/kicadtoNgspice/Convert.py8. TerminalUi fails to load when launched from a different working directory
uic.loadUi("TerminalUi.ui")resolves relative to whatever the process CWD happens to be. Fixed to useos.path.dirname(__file__).Also:
self.Flag = "Flase"was a string instead of a bool.src/frontEnd/TerminalUi.py9. Startup crash when workspace.txt is empty or truncated
readline().split(' ', 1)on an empty file raisesValueErroron unpack. OnlyIOErrorwas caught, so a corrupted workspace.txt would abort startup entirely.src/configuration/Appconfig.py10. TimeExplorer crashes on snapshot operations when no project is open
clear_snapshotsandrestore_snapshotwould proceed with an empty project name, build a bad path, and crash.src/frontEnd/TimeExplorer.py11. NewProject continues executing after permission error dialog
After showing "no write permission" dialog, the function was missing
return None, None, so it would fall through and try to create the project anyway.src/projManagement/newProject.py12. ProjectExplorer: stray
msg.exec()always executes after snapshotA
msg.exec()call was left at the wrong indentation level after a refactor, outside theifblock, so it would pop a dialog every time regardless of outcome.src/frontEnd/ProjectExplorer.pyPyQt5 to PyQt6 renames that #498 missed
These are the things that actually needed fixing beyond what the original PR did:
QMessageBox.Ok/Cancel-->QMessageBox.StandardButton.Ok/StandardButton.Cancel, with|for multiple buttons (not a tuple)QPalette.Base-->QPalette.ColorRole.BaseQLineEdit.Normal-->QLineEdit.EchoMode.NormalQFileDialog.AnyFile-->QFileDialog.FileMode.AnyFilecombo.activated[str].connect(...)-->combo.currentTextChanged.connect(...)-- PyQt6 dropped the indexed signal syntax entirely; this was the most common breakageprocess.pid()-->process.processId()createKicadLibrary.py,ngspice_ghdl.py,TimeExplorer.pyOther fixes found along the way
These weren't from #498 but showed up while testing:
nghdl/src/createKicadLibrary.py,ngspice_ghdl.py: contributor's personal Mac file paths and Mac venv shebang were hardcoded in the Linux fallback. Replaced with/usr/share/kicad/symbols/eSim_Nghdl.kicad_symand#!/usr/bin/env python3.nghdl/src/model_generation.py: home directory was computed viaos.path.abspath(__file__, "..", "..")instead ofos.path.expanduser('~'), pointing at the wrong directory.createSchematicLibwrapped in try/except with error dialog so failures don't disappear silently. Upload button now validates that a file is selected before proceeding.Closes #497 (properly this time).