This interface contains functions for retrieving various symbol information for a debug context, ctx_id. There are also a few functions for updating symbol information.
Prior to using functions in this interface, symbol file(s) containing symbol
information should have been added using the debug_setup
interface, for a context-query that matches the context ID provided to the
function here. Symbol files can also be added in other ways such as from a
tracker or from Eclipse.
Some functions, that do read values or stack, can also be used directly with
symbol files opened with the debug_symbol_file
interface.
All functions in this interface take a context ID ctx_id as
argument. This is the ID passed as an argument to
debug_notification
callbacks or returned from some
debug_query
interface functions.
For all functions that return an attr_value_t
, that return value
will consists of a list with two elements. The first element is an error code
of debugger_error_t
type (see debug_query
interface documentation for definition). The second element depends on the
first. If the first element is Debugger_No_Error
, meaning that
the function went well, then the second element will contain the expected
return value that is specified per function below. If the first element is
another error code, then the second element will be a string describing the
error that occurred.
All addresses used in this interface are virtual addresses.
For functions that take frame as argument, providing
frame = -1 means no frame. This can be used when finding symbols
for functions or global variables. When using other frame than -1
the context has to be active, otherwise no frame will exists and a
Debugger_Context_Is_Not_Active
error will be returned. If the
specified frame cannot be found, then error code
Debugger_Frame_Outside_Of_Known_Stack
will be returned.
Functions that handle stack can only be used with an active context,
otherwise error code Debugger_Context_Is_Not_Active
or
Debugger_Context_Does_Not_Have_State
will be returned depending
on if the context has state or not.
address_source will provide callbacks, cb, with source information for the range specified by address and size. The range must not wrap around the 64-bit limit. Source information will be provided as code areas, which is the source information for a range of continuous addresses matching the same file and line. User data can be passed to the callback using the data argument and will be passed as the first argument in the callback. Each code area matching the range will get a callback with information about the code area in the code_area argument, which is a dictionary with the following elements:
(string)
- File name of the source file
where the specified address is found.(int64)
-
Starting and ending lines in the source file for the address.
end-line is inclusive so if the address just matches
one source line start-line and end-line will be the
same.(int64)
-
Starting and ending columns on the line for address. If column
information is not available in debug information the value will be 0.
end-column is inclusive so the column is included for
address.(uint64)
-
Starting and ending addresses that correspond to the returned line and
column information. end-address is inclusive so this matches the
last byte of the last instruction of this code area. If the code area is
empty then, then end-address will not be present. This can happen
when asking for a line prior to the first executable line.Errors specific to this function:
source_address will provide callbacks, with source information for the line specified by filename, line and column. The column argument will only be useful for binaries with column information in the debug information.
One call to this function will provide as many callbacks as there are code areas matching that source information. The code_area provided to the callback is a dictionary with the same format as for the callback from address_source.
Errors specific to this function:
For binaries without column information, a line is executable if the start-line in the callback matches the asked line.
For binaries with column information one can say that the line is executable if any code area can be found with start-line matching the asked line. When asking for a line and column and the start-line matches a previous line, but the end-line matches the asked line, then one should ask for the column just after end-column to see if the start-line of that code area matches the asked line and if it does then the asked line is considered executable.
stack_depth returns the current stack depth.
Errors specific to this function:
stack_frames returns a list of dictionaries with information about each frame. The executing frame is at position zero in the list. The elements of the stack frame dictionary are:
(uint64)
- For the executing frame this
is the address of the program counter, for all other frames this is the
address that the function will return to.(string)
- The source file for the
frame. Can be nil if no matching file is found.(uint64)
- The source line in the
file for the frame. Will be nil if source-file is nil.(string)
- The function that is
executing in the frame. Can be nil if no function is found.Errors specific to this function:
Debugger_Failed_To_Get_Stack_Frame
- If there are problems
getting stack depth or getting frame info.Debugger_Failed_To_Read
- If a register cannot be read for
some frame.Debugger_Failed_To_Get_PC
- If the program counter
definition cannot be found for the context.local_variables returns a list of names for local variables in the specified frame.
local_arguments returns a list of names of arguments to the function in the specified frame.
Both local_variables and local_arguments can return an
empty list if no local variables or arguments are found. If something goes
wrong while looking up variables or arguments they will return a
Debugger_Lookup_Failure
with more information in the error
string.
expression_value returns the value of an expression, expr, in the specified frame. See note about address_scope further down. The returned value will be of integer type if the expression is of integer type, including if it is an address. Floating-point types will be returned as such. If the expression is a structure, union, class or an array a list containing the elements of that type will be returned.
Errors specific to this function:
expression_type returns the type of an expression,
expr, in the specified frame. See note about
address_scope further down. For most types the return value will
be a string containing the type, for example 'int'
,
'double'
, 'char'
or 'my_own_type_t
.
For pointers the return value will be a list with '*' as the
first argument followed by the type of the pointer, for example ['*',
'void']
or ['*', ['*', 'char']]
.
For qualifiers ('const', 'volatile' or 'restrict') these will be added as an
element to the list, such as ['const', 'char']
or ['volatile',
['*', 'int']]
.
Functions are returned with a '()' string as the first element of
a list, followed by the return type, followed by a list of arguments to the
function. Example: ['*', ['()', 'int', ['int', ['*', ['*',
'char']]]]]
for a function of type int (*)(int, char **)
.
A struct
or union
will return a string
'struct'
, followed by the struct name, if available, then
followed by a list of lists containing the struct member type and name
['struct', 'my_struct', [['int', 'i'], ['float', 'f']]]
as
example. If the struct has been assigned a type with typedef then
the output will be 'typedef'
followed by the name of the
assigned type, then the list of members. An example: ['typedef',
'mytype_t', [['int', 'age'], [['*', 'char'], 'name']]]
. For unions the
string 'struct'
will be replace with the string
'union'
.
A bit field
will return a list containing a string
'bitfield'
followed by the basic type of the bit field,
followed by the size of the bit field. An example: ['bitfield', 'int',
5]
for a variable declared as int var:5
.
For array types expression_type will return a list, ['[]',
array size, array type]
, where the array type is of the same format as
other types for this function. An example: ['[]', 10, 'char']
for a
variable declared as char x[10]
;
Enumerations will be displayed as a list: ['enum', enum name,
members]
. The enum name is the declared name for the
enumeration, if no such name exists this list field will be left out. The
members field will contain a list of [name, value] lists for all
the members of the enumeration. An example: ['enum, 'my_enum',
[['My_Val_0', 0], [My_Val_1, 1]]]
.
dbghelp.dll
.
'typedef'
type.const
qualifier might be shown without
that qualifier.type_info returns information about what base type a type that has been added with typedef has. See note about address_scope further down. The returned value will be a list on the same format as for expression_value.
Errors specific to this function:
type_to_string converts the return value from expression_type or type_info to a readable string and returns that.
Errors specific to this function:
symbol_address takes a frame and a symbol
as arguments and returns a list of addresses that matches that symbol name.
If a single symbol address is wanted near a provided instruction pointer
then the expression_value function can be used with the
expression set as &<symbol>
.
Errors specific to this function:
address_string returns the string at the specified address. The maxlen is used to specify the maximum length of a string to read from memory. If the string at address exceeds the given length the truncated string will be returned, and a terminating null character will be added if needed. A maxlen value of zero means no maximum string length.
Errors specific to this function:
lvalue_write writes a value to a symbol in
the specified frame. The value can be of
integer
types or floating-point
type if the type
of the lvalue is of floating-point
type. The returned value
when the write goes well is nil.
Errors specific to this function:
address_write writes an attr_value_t
of
data
type, value, to the specified
address. Returned value is nil when the write goes well.
Errors specific to this function:
address_read reads size number of bytes from the
specified address. The read data is returned as an
attr_value_t
of data
type.
Errors specific to this function:
struct_members returns a list of all members of a struct,
struct_name. See note about address_scope further
down. Each element of the returned list will be on the format [name,
offset, size]
. The size and offset elements are
usually integers representing the offset into the struct and the size of the
variable. If the struct member is a bit field then size will be a
list on the format [base size, bits]
, where base size is
the number of bytes for the declared base type and bits is the
number of bits the declared for the bit field. For bit fields
offset will be a list on the format [byte offset, bit
offset]
, where byte offset is the offset of in bytes into
the structure and bit offset is the offset in bits from the byte
offset to where the bit field starts. If some member, size or offset cannot
be retrieved then that element will be set as nil. This can for example
occur if a struct member is an anonymous struct or union.
Errors specific to this function:
struct_field returns a list of [offset, size] for a field of a given structure, struct_name. The offset and size are usually integers, but if the field is a bit field then the returned size and offset will be on the same format as for struct_members. See note about address_scope below.
This function can return the same error codes, for the same reasons, as the struct_members function.
The address_scope argument that is provided for several functions can be used to specify where to find the symbol if there are several matches for the provided symbol name or expression. This argument is used to provide an address that tells the function in which scope to search for the symbol. This is only taken in account when no frame (-1) is given as frame. This address can be an address that belongs to a loaded symbol file to prioritize finding symbols from that symbol file.
list_functions and list_global_variables lists all
function or global variable symbols that are known for the given
context. The symbols shown are the ones that have been added with the
add_symbol_file function of the debug_setup
interface. The returned format is a list of dictionaries with the dictionary
elements on the format:
(string)
- The name of the symbol.(uint64)
- The address in memory of the
symbol.(uint64)
- The size of the symbol in
memory.list_source_files lists all source files provided by the debug information of the symbol files for the given context.
SIM_INTERFACE(debug_symbol) { attr_value_t (*address_source)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, uint64 address, uint64 size, void (*cb)(cbdata_call_t data, attr_value_t code_area), cbdata_register_t data); attr_value_t (*source_address)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, const char *NOTNULL filename, uint32 line, uint32 column, void (*cb)(cbdata_call_t data, attr_value_t code_area), cbdata_register_t data); attr_value_t (*address_symbol)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, uint64 address); attr_value_t (*stack_depth)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id); attr_value_t (*stack_frames)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, int min, int max); attr_value_t (*local_variables)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, int frame); attr_value_t (*local_arguments)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, int frame); attr_value_t (*expression_value)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, int32 frame, uint64 address_scope, const char *NOTNULL expr); attr_value_t (*expression_type)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, int32 frame, uint64 address_scope, const char *NOTNULL expr); attr_value_t (*type_info)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, uint64 address_scope, const char *NOTNULL type); attr_value_t (*type_to_string)(conf_object_t *NOTNULL obj, attr_value_t type); attr_value_t (*symbol_address)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, int32 frame, const char *NOTNULL symbol); attr_value_t (*address_string)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, uint64 address, int maxlen); attr_value_t (*lvalue_write)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, int32 frame, const char *NOTNULL symbol, attr_value_t value); attr_value_t (*address_write)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, uint64 address, attr_value_t value); attr_value_t (*address_read)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, uint64 address, unsigned size); attr_value_t (*struct_members)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, uint64 address_scope, const char *NOTNULL struct_name); attr_value_t (*struct_field)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id, uint64 address_scope, const char *NOTNULL struct_name, const char *NOTNULL field); attr_value_t (*list_functions)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id); attr_value_t (*list_global_variables)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id); attr_value_t (*list_source_files)(conf_object_t *NOTNULL obj, const char *NOTNULL ctx_id); }; #define DEBUG_SYMBOL_INTERFACE "debug_symbol"