Suppose I have a buffer buf
whose c string representation is
char* buf = "Hello World \x1c"
When I print this buf in gdb using the command p buf
, I get the following
$1 = "Hello World \034"
Is there a print command or a gdb setting that will print the following instead?
$1 = "Hello World \x1c"
I have tried various format parameters such as /c
and /x
, but none of them get the effect that I am looking for. I have also played with printf but was unable to achieve the desired effect.
Update: I am using "GNU gdb (GDB) 7.0.1-debian".
Update: I have played with x as well.
If I do x/c
it prints octal and decimal for nonprintable characters, and then prints printable characters with the ascii and decimal.
If I do x/s
it outputs exactly the same as the p command.
If I do x/x
it just outputs hex but then we lose the ascii characters for the printable part.
Update: This reference, unless incomplete, suggests that what I desire is not available, but can anyone confirm?
In the absence of an existing solution, I created this gdb command which prints ascii and hex for strings that have mixed printable ascii and non-printable characters. The source is reproduced below.
from __future__ import print_function
import gdb
import string
class PrettyPrintString (gdb.Command):
"Command to print strings with a mix of ascii and hex."
def __init__(self):
super (PrettyPrintString, self).__init__("ascii-print",
gdb.COMMAND_DATA,
gdb.COMPLETE_EXPRESSION, True)
gdb.execute("alias -a pp = ascii-print", True)
def invoke(self, arg, from_tty):
arg = arg.strip()
if arg == "":
print("Argument required (starting display address).")
return
startingAddress = gdb.parse_and_eval(arg)
p = 0
print('"', end='')
while startingAddress[p] != ord("\0"):
charCode = int(startingAddress[p].cast(gdb.lookup_type("char")))
if chr(charCode) in string.printable:
print("%c" % chr(charCode), end='')
else:
print("\\x%x" % charCode, end='')
p += 1
print('"')
PrettyPrintString()
To use this, one can simply put the source AsciiPrintCommand.py
and then run the following in gdb. For convenience, one can put put the above source command into their $HOME/.gdbinit
.
ascii-print buf
"Hello World \x1c"
Here are step-by-step instructions for gdb v12.1 on Ubuntu x64 22.04 LTS:
1 - Create a folder called ~/.config/gdb"
2 - In that folder create a text file called "AsciiPrintCommand.py".
3 - Copy this solutions source code into that file - Important remove all excess indentation from all lines (e.g. 1st line should read "from" and not " from"
4 - In that same folder create another file "gdbinit" containing...
set output-radix 16
source ~/.config/gdb/AsciiPrintCommand.py
5 - run up gdb
6 - to test it worked type ---> ascii-print "hello"
This method works for starting gdb from any dir, and also from inside a 32bit schroot. Putting these files into ~/.config avoids the gdb "file or directory doesn't exist" bug when trying to gdbinit from mounted paths.