Skip to content

v2.1.0

Choose a tag to compare

@JeanExtreme002 JeanExtreme002 released this 19 Aug 04:12
· 15 commits to main since this release
29d2f69

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 no QCloseEvent, so the cleanup that lived in closeEvent never 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 queued finished no longer retires the replacement worker (which scheduled a live QThread for 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, and application.main releases the handle the window is actually attached to instead of leaking the current target's on a process switch (#82)
  • Memory Map: no more OverflowError above 2^63. Linux's [vsyscall] region sits at 0xffffffffff600000, past QVariant's qint64 limit, 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 calling main(), 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_threads documents this platform split now, in contrast with get_memory_regions and get_modules, which raise ProcessIDNotExistsError everywhere (#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