v2.1.0
What's changed
This release is all about the GUI app: four issues reported against it, plus the teardown and threading gaps that came with them.
Fixed
- Process picker no longer fights the user. The list re-enumerates every 3 s, and each tick restored the selected row — which scrolled the view back to it, making a long list impossible to browse — and echoed the selected PID over whatever you had typed in the Process: field. Both are gone. A click (single or double) now aims the field at the row it carries, and hiding the selected row with the Filter box no longer re-aims the pick at a process you never chose (#75, #84)
- An exited target is reported once, not forever. Selecting a process that had already exited — or watching one exit with a tool window open — stacked a modal per failed poll: 332 dialogs in six seconds in a headless repro, enough that the app had to be killed from another terminal. A failure is now reported only when it changes what you see (the first fetch, or the one that makes the poll give up after 3 s), the status line says the poll stopped, and File → Change Process… tears down every dialog still holding the old handle. The Hex Viewer got the same treatment — it was logging the same read failure up to 20×/s into the Log Console (#74, #82)
- Dialog teardown now runs however a window is dismissed.
QDialog.done()delivers noQCloseEvent, so the cleanup that lived incloseEventnever ran for a dialog's own Close button or Esc: every worker-bearing dialog kept polling, hidden and unreachable, and leaked a thread per open/close cycle. Related fixes: a queuedfinishedno longer retires the replacement worker (which scheduled a liveQThreadfor deletion and aborted the process), the cheat poller checks its stop flag per entry so a blown join can't write through a closed handle, andapplication.mainreleases the handle the window is actually attached to instead of leaking the current target's on a process switch (#82) - Memory Map: no more
OverflowErrorabove 2^63. Linux's[vsyscall]region sits at0xffffffffff600000, pastQVariant'sqint64limit, so opening the memory map crashed. The address is now held on the Python side (#77) - Ctrl+C closes the app from a terminal. SIGINT is handled on the console-script path only, and the previous handler is restored on exit (#76, #78)
Changed
- The console script now points at
PyMemoryEditor.app.application:main_cli, a thin wrapper that adds the Ctrl+C handling. Embedders and tests should keep callingmain(), which touches no signal handlers (#78) - Address and size columns in Memory Map, Modules and Pointer Scan render in a monospace font, so addresses line up for visual comparison (#77)
- Threads treats two consecutive empty enumerations as the target being gone — on Linux and Windows an exited process enumerates nothing rather than raising, so that window used to sit at "0 thread(s)" while its neighbours reported the process dead.
get_threadsdocuments this platform split now, in contrast withget_memory_regionsandget_modules, which raiseProcessIDNotExistsErroreverywhere (#82) - ~1000 lines of new app tests, and macOS dropped from the CI matrix
Install
pip install --upgrade PyMemoryEditor📖 Full documentation: pymemoryeditor.readthedocs.io
Full Changelog: v2.0.1...v2.1.0