maintain separate Ghidra state for each Python shared interpreter #69
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.
Switching to Python shared interpreters introduced a significant problem: maintaining independent Ghidra state at the
builtins
scope for each Python shared interpreter running in the sameJava
process.This problem stems from the fact that by design Python shared interpreters share all imported modules, including
builtins
, so any modification tobuiltins
affects all shared interpreters running in the sameJava
process. For example, we storecurrentProgram
inbuiltins
so all modules can access it without an explicit import. Unfortunately, if shared interpreterA
setscurrentProgram
followed by shared interpreterB
settingcurrentProgram
then shared interpreterA
's next access ofcurrentProgram
could be invalid. This issue extends to allGhidraScript
state variables andFlatProgramAPI
functions that we store inbuiltins
. Additionally, we modify thesys
module to redirectstdout
andstderr
to the correct Ghidra window, e.g. Ghidra console window. This issue also extends to these modifications as thesys
module is also shared across all shared interpreters.This PR proposes to fix the issues described above by using decorated Python methods that retrieve the correct
GhidraScript
state variable orFlatProgramAPI
function when accessed frombuiltins
. The independent state is maintained using the thread ID of the Java thread used to run the shared Python interpreter. For example, shared interpreterA
is executed from Java thread10
and shared interpreterB
is executed from Java thread11
. All Ghidra-relatedbuiltins
accesses made by the shared interpreter'sA
andB
are redirected to the specific cached objects based on the interpreter's Java thread ID,10
or11
.This PR contains breaking changes.
GhidraScript
state variables:monitor
currentProgram
currentAddress
currentLocation
currentSelection
currentHighlight
must now be accessed via a function call e.g.
monitor()
,currentProgram()
, etc.. This diverts from the default behavior used by previous Ghidrathon versions where theseGhidraScript
state variables could be accessed directly by name e.g.monitor
. Any Python scripts written for previous Ghidrathon versions must be updated accordingly.closes #68
closes #67
closes #65
closes #71
To test:
To do:
GhidraScript
variables are now function callsGhidraScript
variables in the global scope, e.g.currentProgram = currentProgram()
in the global can result in outdated object references