I'm debugging an extension. It's a ProgramTableChooserDialog that contains rows with program and address columns and can navigate to whatever program/address is in a row.
An old ProgramTableChooserDialog version threw an exception. I've written a new version, but I can't get Ghidra to see it. I've even renamed ProgramTableChooserDialog.class to PTCD.c and added the following lines to the script that creates the dialog:
printf("%s\n", ProgramTableChooserDialog.class.getResource('/' + ProgramTableChooserDialog.class.getName().replace('.', '/') + ".class"));
ProgramTableChooserDialog table = new ProgramTableChooserDialog(
tool, null, currentProgram, "Callers", null, false);
The printf writes"null" to the console, as expected. But the ctor runs and eventually throws the old exception. How do I get Ghidra to see the current class file?
I'm using Eclipse (GhidraDev) to launch my project. Although ProgramTableChooserDialog.class doesn't exist, I get the following when I run my script:
null
Error running script: ListCallers.java
java.lang.NullPointerException
at docking.widgets.table.threaded.GThreadedTablePanel.initializeModel(GThreadedTablePanel.java:114)
at docking.widgets.table.threaded.GThreadedTablePanel.(GThreadedTablePanel.java:102)
at ghidra.util.table.GhidraThreadedTablePanel.(GhidraThreadedTablePanel.java:35)
at contrib.util.table.ProgramTableChooserDialog$TableChooserDialogPanel.(ProgramTableChooserDialog.java:347)
at contrib.util.table.ProgramTableChooserDialog.buildMainPanel(ProgramTableChooserDialog.java:112)
at contrib.util.table.ProgramTableChooserDialog.(ProgramTableChooserDialog.java:94)
at ListCallers.run(ListCallers.java:362)
The exception is being thrown because the table row type (ProgramAddressableRowObject) loaded as part of my extension isn't matching my extension ProgramAddressableRowObjectToAddressTableRowMapper's source type. The match is failing, although the 2 classes are the same (both ProgramAddressableRowObject), because the classes are loaded by 2 different class loaders. The row type is loaded by ghidra.app.script.JavaScriptClassLoader@7695fdbc and the mapper's source type is loaded by jdk.internal.loader.ClassLoaders$AppClassLoader@41906a77 (GhidraScript).
I'm using Ghidra 9.1.1 on Windows 10. I'd like to use Ghidra 9.1.2, but it throws an exception when I try to load any of the programs in my project:
2020-04-22 12:02:44 ERROR (TaskBuilder$TaskBuilderTask) Task Error: Loading language 'ARM:LE:32:v8' - Uncaught Exception: java.lang.RuntimeException: org.xml.sax.SAXParseException; lineNumber: 10251; columnNumber: 25; XML document structures must start and end within the same entity. java.lang.RuntimeException: org.xml.sax.SAXParseException; lineNumber: 10251; columnNumber: 25; XML document structures must start and end within the same entity.
at ghidra.xml.ThreadedXmlPullParserImpl.checkForException(ThreadedXmlPullParserImpl.java:122)
at ghidra.xml.ThreadedXmlPullParserImpl.waitForNextElement(ThreadedXmlPullParserImpl.java:168)
at ghidra.xml.ThreadedXmlPullParserImpl.hasNext(ThreadedXmlPullParserImpl.java:154)
at ghidra.xml.ThreadedXmlPullParserImpl.peek(ThreadedXmlPullParserImpl.java:181)
at ghidra.app.plugin.processors.sleigh.symbol.SymbolTable.restoreSymbolHeader(SymbolTable.java:132)
at ghidra.app.plugin.processors.sleigh.symbol.SymbolTable.restoreXml(SymbolTable.java:112)
at ghidra.app.plugin.processors.sleigh.SleighLanguage.restoreXml(SleighLanguage.java:872)
at ghidra.app.plugin.processors.sleigh.SleighLanguage.readSpecification(SleighLanguage.java:842)
at ghidra.app.plugin.processors.sleigh.SleighLanguage.initialize(SleighLanguage.java:133)
at ghidra.app.plugin.processors.sleigh.SleighLanguage.
at ghidra.app.plugin.processors.sleigh.SleighLanguageProvider.getNewSleigh(SleighLanguageProvider.java:112)
at ghidra.app.plugin.processors.sleigh.SleighLanguageProvider.getLanguage(SleighLanguageProvider.java:99)
at ghidra.program.util.DefaultLanguageService$LanguageInfo.lambda$getLanguage$0(DefaultLanguageService.java:385)
at ghidra.util.task.TaskBuilder$TaskBuilderTask.run(TaskBuilder.java:303)
at ghidra.util.task.Task.monitoredRun(Task.java:126)
at ghidra.util.task.TaskRunner.lambda$startTaskThread$1(TaskRunner.java:94)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.xml.sax.SAXParseException; lineNumber: 10251; columnNumber: 25; XML document structures must start and end within the same entity.
at java.xml/com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1243)
at java.xml/com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:635)
at ghidra.xml.ThreadedXmlPullParserImpl$ContentHandlerRunnable.run(ThreadedXmlPullParserImpl.java:267)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
... 3 more
It may be that ghidra is using the old ListCallers.class instead of recompiling the script and running that. You can try deleting ListCallers.class and rerunning the script. I've encountered this a few times but always attributed it to my setup since I don't like Eclipse and instead use vscode.
You can find the compiled script class files in %HOMEPATH%/.ghidra/.ghidra_9.1.1_PUBLIC/dev/ghidra_scripts/bin
That was the problem...I was focused on the wrong file. Should've thought of that.
Thanks!
That was the problem...I was focused on the wrong file. Should've thought of that.
Thanks!
No problem. I think it's because the scripts are only recompiled if the java file is newer then the previously compiled class. If you change a class the script is using, ghidra doesn't know it needs to recompile the script.
Most helpful comment
No problem. I think it's because the scripts are only recompiled if the java file is newer then the previously compiled class. If you change a class the script is using, ghidra doesn't know it needs to recompile the script.