Examining Data

Posted by Beetle B. on Fri 17 January 2020

Normally you would use p to examine data. You can also use a Python pretty printer.

print EXPR

You can use the x command to see a more low level view of the data (memory contents?).

ptype EXPR gives you information about the fields of a struct/class.

explore gives you a more interactive view starting from a higher/abstract level. It requires a compile time option for Python. Useful if you have a class that has other class objects as members.

Expressions

You can treat parts of memory as arrays.

You can specify a variable in terms of the file/function it is defined in.

Ambiguous Expressions

If there is ambiguity in the expression (e.g. overloaded function name), it may present you with a menu of options.

Program Variables

Sometimes a local variable has the wrong value. This may be due to stepping by machine instructions, where it can take multiple machine instructions to update the frame.

Also, beware that optimizations may eliminate variables.

Artificial Arrays

It is often useful to print out several successive objects of the same type in memory; a section of an array, or an array of dynamically determined size for which only a pointer exists in the program.

You can do this by referring to a contiguous span of memory as an “artificial array”, using the binary operator ‘@’. The left operand of ‘@’ should be the first element of the desired array and be an individual object. The right operand should be the desired length of the array.

Output Formats

You may want to display the value of a variable in a different format (e.g. number in hex, etc). Do print/F where F is a format letter:

  • x: Print the bits as a hex integer.
  • d: Print as signed decimal
  • u: Print as unsigned decimal
  • o: Print as octal
  • t: Print as binary (t is for two)
  • a: Print as address
  • c: Print as character constant.
  • f: Print as floating point number
  • s: Treat as string
  • z: Same as x but with leading zeros to pad
  • r: Print as “raw” (bypasses Python pretty printer)

Examining Memory

Use x to examine the memory. Read for details.

Automatic Display

If you find that you want to print the value of an expression frequently (to see how it changes), you might want to add it to the “automatic display list” so that GDB prints its value each time your program stops.

Essentially a watchlist.

To add an expression to the display list, do display EXPR. Can use format expressions.

To remove an expression from the display list, do delete display N (you can specify a range). You can also use disable display to temporarily turn them off. Use enable to re-enable.

To see all automatic display entries, do info display.

Pretty Printing

Introduction

info pretty-printer will display all installed ones.

Value History

Values printed by the ‘print’ command are saved in the GDB “value history”. This allows you to refer to them in other expressions.

To refer to any previous value, use ‘\(' followed by the value's history number. The way 'print' labels its output is designed to remind you of this. Just '\) refers to the most recent value in the history, and ‘

\begin{equation*} ' refers to the value before that. ' \end{equation*}

N’ refers to the Nth value from the end; ‘

\begin{equation*} 2' is the value just prior to ' \end{equation*}

, ‘

\begin{equation*} 1' is equivalent to ' \end{equation*}

, and ‘$\(0' is equivalent to '\).

For example, suppose you have just printed a pointer to a structure and want to see the contents of the structure. It suffices to type

p *$

If you have a chain of structures where the component ‘next’ points to the next one, you can print the contents of the next one with this:

p *$.next

You can print successive links in the chain by repeating this command–which you can do by just typing <RET>.

show values N shows the last \(N\) values.

Convenience Variables

Convenience variables are prefixed with ‘\('. Any name preceded by '\) can be used for a convenience variable, unless it is one of the predefined machine-specific register names

show convenience

init-if-undefined $VARIABLE = EXPRESSION

  • $_ has the last address examined by x
  • $__ has the value in the last address examined by x.
  • $exitcode
  • $exitsignal
  • $exception
  • $thread (number of current thread)

And others.

Convenience Functions

  • $isvoid (EXPR)
  • $regex(STR, REGEX)
  • $streq(STR1, STR2)

And others for string length, name of caller, etc.

Registers

You can refer to machine register contents, in expressions, as variables with names starting with ‘$’. The names of registers are different for each machine; use ‘info registers’ to see the names used on your machine.

info registers’ Print the names and values of all registers except floating-point and vector registers (in the selected stack frame).

info all-registers’ Print the names and values of all registers, including floating-point and vector registers (in the selected stack frame).

And more. Read.

Floating Point Hardware

info float

May not work on all machines.

Vector Unit

Operating System Auxiliary Information

Depends on the OS, but may be able to get stuff like number of CPUs, open files, kernel modules, processes, threads, etc.

Memory Region Attributes

Copy Between Memory and a File

dump, append write data to a file. restore reads it.

How To Produce a Core File From Your Program

You can generate core files.

Character Sets

Read if having issues with character sets.

Caching Data of Targets

GDB caches data exchanged between the debugger and a target. Each cache is associated with the address space of the inferior. Note Inferiors and Programs, about inferior and address space. Such caching generally improves performance in remote debugging (note Remote Debugging), because it reduces the overhead of the remote protocol by bundling memory reads and writes into large chunks. Unfortunately, simply caching everything would lead to incorrect results, since GDB does not necessarily know anything about volatile values, memory-mapped I/O addresses, etc.

Search Memory

You can search memory for a sequence of bytes.

Value Sizes

Whenever GDB prints a value memory will be allocated within GDB to hold the contents of the value. It is possible in some languages with dynamic typing systems, that an invalid program may indicate a value that is incorrectly large, this in turn may cause GDB to try and allocate an overly large ammount of memory.

This section mitigates that.

tags : gdb