A simple debug session

QNX SDP8.0Programmer's GuideDeveloper

In this example, we'll be debugging our Hello, world! program via a TCP/IP link. We go through the following steps:
  • configuring the target
  • compiling for debugging
  • starting the debug session
  • using basic debugging commands

Configure the target

Let's assume an x86_64 target using a basic TCP/IP configuration. The following lines (from the buildfile you'd use to create the OS image) show what's needed to host the sample session:
io-sock -m phy -m usb -d axge
if_up -p axge0
ifconfig axge0 192.0.2.172/24
devc-pty &
[+session] pdebug 8000 &

The above specifies that the host IP address is 10.0.1.172. The pdebug agent is configured to use port 8000.

You could instead run qconn on the target, and the behavior would be similar: qconn listens on the same port and starts pdebug if a target qnx ip:port connection comes in, and then the communication would be the same as with pdebug alone.

Compile for debugging

We'll be using the x86_64 compiler. Note the -g option, which makes the compiler include debugging information:
$ qcc -V gcc_ntox86_64 -g -o hello hello.c  

Start the debug session

For this simple example, the source can be found in our working directory. First, let's start the session; to reduce document clutter, we'll run the debugger in quiet mode:
ntox86_64-gdb -quiet
The gdb debugger provides its own shell; by default its prompt is (gdb). Specify the target IP address and the port used by pdebug:
(gdb) target qnx 10.0.1.172:8000
Remote debugging using 10.0.1.172:8000
MsgNak received - resending
Remote target is little-endian
Upload the debug executable to the target. Note that the file has to be in the target system's pathname space, so we can get the executable via a network filesystem, sftp, or, if no filesystem is present, via the upload command:
(gdb) upload hello /tmp/hello
Load symbolic debug information from the current working directory (here, hello must reside on the host system):
(gdb) file hello
Reading symbols from hello...done.

You don't need to use the file command if you specify the executable name when you start gdb (e.g., ntox86_64-gdb -quiet hello).

Start the program:
(gdb) run hello
Starting program:  /tmp/hello
Trying to find symbol file for ldqnx-64.so.2
Set a breakpoint on main():
(gdb) break main
Breakpoint 1 at 0x80483ae: file hello.c, line 8.
Allow the program to continue to the breakpoint found at main():
(gdb) c
Continuing.
Breakpoint 1, main () at hello.c:8
8       gettimeofday (&when, NULL);

Continue to debug the program as necessary.

Basic debugger commands

While you're in a debug session, you can use any of the following commands as the next action:
next
Continue to the next source line in the current (innermost) stack frame.
list
List the specified function or line.
break
Set a breakpoint on the specified function or line.
help
Get the help main menu.
help data
Get the help data menu.
help inspect
Get help for the inspect command.
inspect y
Inspect the contents of variable y.
set y=3
Assign a value to variable y.
bt
Get a backtrace.

For more information about these commands and their arguments, see https://www.gnu.org/software/gdb/documentation/, or use the help cmd command in gdb.

Let's see how to use some of these basic commands. First, here's the list command:
(gdb) list
3
4   main () {
5       struct timeval when;
6       int x,y,z;
7
8       gettimeofday (&when, NULL);
9       printf ("Hi ya!\n");
10
11      x=3;
12      y=2;
Press Enter to repeat the last command:
(gdb) <enter>
13      z=3*2;
14
15      exit (0);
16  }
Break on line 11:
(gdb) break 11
Breakpoint 2 at 0x80483c7: file hello.c, line 11.
Continue until the first breakpoint:
(gdb) continue
Continuing.
Hi ya!
Breakpoint 2, main () at hello.c:11
11      x=3;

Notice that the above command went past the printf() statement at line 9, so the output from the call is displayed.

Inspect variable y, using the short form of the inspect command:
(gdb) inspect y
$1 = -1338755812
Get some help on the step and next commands:
(gdb) help s
Step program until it reaches a different source line.
Usage: step [N]
Argument N means step N times (or till program stops for another reason).
(gdb) help n
Step program, proceeding through subroutine calls.
Usage: next [N]
Unlike "step", if the current source line calls a subroutine,
this command does not enter the subroutine, but instead steps over
the call, in effect treating it as a single source line.
Go to the next line of execution:
(gdb) next
12      y=2;
(gdb) next
13      z=3*2;
(gdb) inspect z
$2 = 1
(gdb) next
15      exit (0);
(gdb) inspect z
$3 = 6
Continue program execution:
(gdb) continue
Continuing.

Program exited normally.
Quit the debugger session:
(gdb) quit
The program is running. Exit anyway? (y or n) y
Page updated: