NationalSecurityAgency/ghidra · error · IllegalArgumentException
DataType %s has dynamic length
Error message
DataType %s has dynamic length
What it means
Thrown by InputsTableModel.addPointerVars when the data type pointed to by a pointer argument reports length -1, meaning it is dynamically sized. The function emulator needs a concrete byte count to allocate (and dereference) pointer destination storage; variable-length types like strings or zero-terminated structures cannot be allocated to a fixed size.
Source
Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/emulation/DebuggerEmulateFunctionDialog.java:634
byte[] addrToBytes(Address address, int length) {
return Utils.longToBytes(address.getOffset(), length, language.isBigEndian());
}
void allocate(int length) {
// Extension point
}
abstract T newRow(String name, VarStorage storage, DataType type);
public void addPointerVars(int count) {
if (!(getBaseDataType(from.getType()) instanceof Pointer ptr)) {
return;
}
DataType dest = ptr.getDataType();
int length = dest.getLength();
int alignedLen = dest.getAlignedLength();
if (length == -1) {
throw new IllegalArgumentException(
"DataType %s has dynamic length".formatted(dest));
}
allocate((alignedLen * (count - 1)) + length);
AddressSpace space = function.getProgram().getLanguage().getDefaultDataSpace();
int offset = 0;
if (!(DataTypeUtilities.getBaseDataType(dest) instanceof Composite composite)) {
for (int i = 0; i < count; i++) {
VarStorage deref = from.getStorage().deref(language, space, offset, length);
String name = count == 1 // LATER: Cull unnecessary ()s?
? "*(%s)".formatted(from.name)
: "(%s)[%d]".formatted(from.name, i);
findRow(into, name).ifPresent(into::delete);
T row = newRow(name, deref, dest);
into.add(row);
added.add(row);
View on GitHub (pinned to d5f144c24d)
Solutions
- Change the argument's declared type from a dynamic type to a fixed-length equivalent (e.g., char* -> a fixed-size byte array type) before emulation.
- Resolve the pointer destination to a concrete DataType with a known length in the program's data type manager.
- Avoid enabling pointer-variable allocation (the 'count > 0' path) for inputs whose target type is dynamic.
- Replace a dynamic string type with a fixed char[ N ] array type for the emulation session.
Example fix
// before
DataType dest = ptr.getDataType();
int length = dest.getLength(); // -1 for dynamic types
// allocate((alignedLen*(count-1))+length) -> underflows / throws
// after
DataType dest = ptr.getDataType();
if (dest.getLength() == -1) {
Msg.warn(this, "Skipping dynamic-length pointer dest: " + dest);
return;
} Defensive patterns
Strategy: validation
Validate before calling
DataType dest = ((Pointer) DataTypeUtilities.getBaseDataType(from.getType())).getDataType(); boolean ok = dest.getLength() != -1;
Type guard
static boolean hasFixedLength(Pointer p) {
return p.getDataType() != null && p.getDataType().getLength() != -1;
} Try / catch
try {
tableModel.addPointerVars(count);
} catch (IllegalArgumentException e) {
Msg.showWarn(this, null, "Cannot add pointer vars", e.getMessage());
} Prevention
- Resolve pointer target types to concrete fixed-length types before emulation.
- Avoid dynamic types (strings, variable structs) as pointer destinations.
When it happens
Trigger: Calling addPointerVars(count) on an input row whose base data type is a Pointer, where ptr.getDataType().getLength() returns -1 (e.g., the pointer targets a char* / TerminatedStringDataType, or a variable-length structure).
Common situations: Functions taking char*/string arguments; pointers to forward-declared or undefined types Ghidra treats as dynamic; pointer destinations to variable-length composites.
Related errors
- Sleigh language required
- Input %s conflicts: 0x%s != 0x%s
- Cannot encode '<value>' for <dataTypeDisplayName>: <message>
- Emulation requires a Sleigh language
- Timed out reading or writing target
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/a69734779ce3e5e4.
Report an issue: GitHub.