How can I make gdb print unprintable characters of a string in hex instead of octal while preserving the ascii characters in ascii form?

You might use the x command to dump the memory your char-pointer points to:

(gdb) x/32xb buf

shows the first 32 bytes.

See

(gdb) help x

for details.


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"

For anyone else who shares the irritation with octal escape-sequences in GDB, it's easy to fix (if you're prepared to build GDB yourself): in gdb/valprint.c, find the comment:

/* If the value fits in 3 octal digits, print it that
                     way.  Otherwise, print it as a hex escape.  */

and comment out the following 4 lines - all escape-sequences will then be printed as hex.