| Previous | Contents | Index |
The Ladebug debugger lets you debug your programs at the machine-code level as well as at the source-code level. Using debugger commands, you can examine and edit values in memory, print the values of all machine registers, and step through program execution one machine instruction at a time.
Only those users familiar with machine-language programming and executable-file-code structure will find low-level debugging useful.
For more information on the Ladebug commands mentioned in this chapter,
see Part 5.
15.1 Examining Memory Addresses
You can examine the value contained at an address in memory as follows:
The <examine address> command has two main syntaxes. The following syntax prints a range of addresses by specifying the beginning and end of the range:
|
start_address, end_address / mode |
If a symbol precedes the slash (/) in an address expression, you may need to enclose the expression in parentheses. For example:
(ladebug) ($pc), ($pc+12) / i |
The following command syntax prints a range of addresses by specifying the beginning address and the total number of memory locations display:
|
start_address / count mode |
You can enter memory addresses in decimal or in hexadecimal by preceding the number with 0x. The mode variable determines how the values are displayed.
Example 15-1 shows how to disassemble a range of memory.
| Example 15-1 Disassembling Values Contained in a Range of Addresses |
|---|
(ladebug) 0x120001180, 0x120001185 / i [main:4, 0x120001180] addq zero, 0x1, t0 [main:4, 0x120001184] stl t0, 24(sp) (ladebug) 0x120001180 / 2 i [main:4, 0x120001180] addq zero, 0x1, t0 [main:4, 0x120001184] stl t0, 24(sp) (ladebug) |
In this example, the same range of addresses was accessed using start_address command in both the end_address syntax and the /
count syntax.
15.1.2 Using Pointer Arithmetic
You can use C and C++ pointer-type conversions to display the contents
of a single address in decimal. Using the print command, the syntax is as follows:
print *(int *)(address)
Using the same pointer arithmetic, you can use the assign command to alter the contents of a
single address. Use the following syntax:
assign *(int *)(address) = value
Example 15-2 shows how to use pointer arithmetic to examine and change the contents of a single address.
| Example 15-2 Using Pointer Arithmetic to Display and Change Values in Memory |
|---|
(ladebug) print *(int*)(0x10000000) 4198916 (ladebug) assign *(int*)(0x10000000) = 4194744 (ladebug) print *(int*)(0x10000000) 4194744 (ladebug) |
The printregs command prints the values of all machine-level registers. The registers displayed by the debugger are machine dependent. The values are in decimal or hexadecimal, depending on the value of the $hexints variable (the default is 0, decimal). The register aliases are shown; for example, $r1 [$t0].
Example 15-3 shows Tru64 UNIX Alpha machine-level registers.
| Example 15-3 Printing Machine Registers on the Tru64 UNIX Alpha Platform |
|---|
(ladebug) printregs $r0 [$v0] = 10 $r1 [$t0] = 1 $r2 [$t1] = 4831844048 $r3 [$t2] = 5368719424 $r4 [$t3] = 0 $r5 [$t4] = 0 $r6 [$t5] = 4396972783304 $r7 [$t6] = 2 $r8 [$t7] = 10 $r9 [$s0] = 337129856 $r10 [$s1] = 337127744 $r11 [$s2] = 4396973344608 $r12 [$s3] = 0 $r13 [$s4] = 5368847640 $r14 [$s5] = 5368753616 $r15 [$s6] = 20 $r16 [$a0] = 1 $r17 [$a1] = 4831835496 $r18 [$a2] = 4831835512 $r19 [$a3] = 4831835848 $r20 [$a4] = 4396981193976 $r21 [$a5] = 5 $r22 [$t8] = 9 $r23 [$t9] = 9 $r24 [$t10] = 4831842472 $r25 [$t11] = 1648 $r26 [$ra] = 4831842828 $r27 [$t12] = 4831842912 $r28 [$at] = 4396981208928 $r29 [$gp] = 5368742064 $r30 [$sp] = 4831835408 $r31 [$zero]= 4831842928 $f0 = 0.1 $f1 = 0 $f2 = 0 $f3 = 0 $f4 = 0 $f5 = 0 $f6 = 0 $f7 = 0 $f8 = 0 $f9 = 0 $f10 = 0 $f11 = 0 $f12 = 0 $f13 = 0 $f14 = 2.035550460865936e-320 $f15 = 4120 $f16 = 0 $f17 = 0 $f18 = 0 $f19 = 0 $f20 = 0 $f21 = 0 $f22 = 0 $f23 = 0 $f24 = 0 $f25 = 0 $f26 = 0 $f27 = 0 $f28 = 0 $f29 = 0 $f30 = 0 $f31 = 0 $pc = 0x120001270 (ladebug) |
The stepi and nexti commands let you step through program execution incrementally, like the step and next commands described in the Command Reference section. The stepi and nexti commands execute one machine instruction at a time, as opposed to one line of source code. Example 15-4 shows stepping at the machine-instruction level.
| Example 15-4 Stepping Through Program Execution One Machine Instruction at a Time |
|---|
(ladebug) stop in main
[#1: stop in main ]
(ladebug) run
[1] stopped at [main:4 0x120001180]
4 for (i=1 ; i<3 ; i++) {
(ladebug) stepi
stopped at [main:4 0x120001184] stl t0, 24(sp)
(ladebug) [Return]
stopped at [main:5 0x120001188] ldl a0, 24(sp)
(ladebug) [Return]
stopped at [main:5 0x12000118c] ldq t12, -32664(gp)
(ladebug) [Return]
stopped at [main:5 0x120001190] bsr ra,
(ladebug) [Return]
stopped at [factorial:12 0x120001210] ldah gp, 8192(t12)
(ladebug)
|
At the machine-instruction level, you can step into, rather than over, a function's prolog. While within a function prolog, you may find that the stack trace, variable scope, and parameter list are not correct. Stepping out of the prolog and into the actual function updates the stack trace and variable information kept by the debugger.
Single-stepping through function prologs that initialize large local variables is slow. As a workaround, use the next command.
This chapter describes debugging programs running on remote systems. A remote debugger consists of a server running on the target system and a client (the debugger) running on the host system. Once connected to the target system, you use Ladebug to debug your program in the same way you debug your programs running locally.
For a detailed description of writing a remote debugger server, see
Appendix C.
16.1 Remote Debugging Environment
The remote debugging environment consists the following components that interact through the remote debugger protocol:
The functionality available in a remote debugging session depends in part on which debugger server you are using. For Tru64 UNIX Version 4.0-6, this server is the server for the EB64 Alpha Evaluation Board (see Section 16.6) or Tru64 UNIX, or a server that you write for your own Alpha environment (see Appendix C).
The Ladebug server provided with DIGITAL UNIX Version 4.0-6 (or later)
is not compatible with versions of the debugger earlier than Version
4.0-6. (This incompatibility affects you only if you use remote
debugging.) The incompatibility stems from a security enhancement
introduced in Version 4.0-6: The server checks that a connect request
is from a privileged port.
16.2 Reasons for Remote Debugging
There are several cases in which you would use a remote debugger:
Remote debugging with Ladebug uses a client/server model. In this model, the host system, or client, initiates a connection to the target hardware and server software, which processes client requests.
Ladebug supports remote debugging in various client/server configurations. Figure 16-1 shows two configurations that use a single file system.
Figure 16-1 Client/Server Model with a Single or a Shared File System
In configuration A, the client and server are implemented on a single machine which connects to a file system.
In configuration B, a host system client is connected to a remote server through TCP/IP. Both host and target systems share the same file system.
A host system client can also be connected to a remote server in a configuration that employs separate file systems, as shown in Figure 16-2.
In this case, you must specify the -rfn option with the remote file name and have a locally accessible binary with debugger information. |
Figure 16-2 Client/Server Model with Separate File Systems
In configurations A, B, and C in Figure 16-1 and Figure 16-2, the user program resides on the target system. The host machine interacts with the target system in the following way:
Table 16-1 describes the client/server concepts for remote debugging. Section 16.4 describes the tasks for remote debugging.
| Client | Server |
|---|---|
| Is Ladebug debugger. | Is remote debugger server. |
| Runs on host system. | Runs on target hardware (for example, EB64 or Tru64 UNIX Alpha. ) |
| Makes requests to server. | Controls the process being debugged. |
| Is responsible for all access to source files and symbol table. | Is not responsible. |
| Uses debug protocol; sends protocol commands to the server. | Uses debug protocol; receives protocol commands and sends responses. |
| Contains information about the process being debugged. | Contains information about the processes' environment. |
| Does not control processes. | Server controls a single process; server deamon controls multiple processes (messages to the server containing a server ID). |
This section describes general tasks to debug programs running on remote systems. The tasks include:
The server daemon must be running on the target system before you can remotely debug programs on that target. You can start the server daemon either from a system startup file or interactively from the command line.
Under certain conditions, running the server daemon negatively affects the security of your system. If you are running an old server, there may be a security problem (see the documentation for that server). An individual user ID can be protected by prohibiting remote access from a particular host (or from all hosts) in the .rhosts and the hosts.equiv files. On Tru64 UNIX machines, .rhosts must have rw privileges only for the owner, with no privileges for the group and others. |
For example, to start the server daemon interactively and output system messages to a log file, log in as superuser then start the server daemon as follows:
$ /usr/bin/ladebug-server > ladebug-server.log & Ladebug remote debug server deamon starting /usr/bin/ladebug-server : server is servdb.ptl.dss.com (11.18.49.164) ... |
When you start the debugger you also start the user program and connect to the server.
Use the -rn command-line option, which specifies the IP name or address of the machine on which the server deamon is running and on which you want your user program to run. Specifying this command-line option is the only difference between starting the debugger to debug a remote application and starting the debugger to debug a local one.
If you start the debugger without specifying the process ID (-pid) , it starts a debuggee process in the remote node running the indicated image file. If you do not specify the user name on the remote node (-ru) , it uses the local user name.
For example, if you are connecting to the target system servdb to debug the user program ~/work/test/hello and the file system is shared:
$ ladebug -rn servdb /work/test/hello Welcome to the Ladebug Debugger Version 3.0 ------------------ object file name: /usr/users/dss/work/test/hello machine name: servdb Reading symbolic information ...done |
If you start the debugger and specify a process ID, the debugger connects to the process in the remote node running the process. If the specified process ID does not exist, the server returns an error and refuses connection.
If you are connecting to a server that does not share the same file system, specify the -rfn option with the -rn option. See Section 16.5 for detailed descriptions of all the remote debugging command-line options. |
You debug a user program running on the target system the same way as you would a local program. Note the following differences:
The following example shows the result of running user program ~/work/test/hello on remote node servdb:
(ladebug) stop in main; run
[#1: stop in main ]
[1] stopped at [main:6 0x120001fa0]
6 (void) printf("Hello, world !\n");
(ladebug) cont
Thread has finished executing
(ladebug)
|
Note that the output of the program is not displayed after the cont command. With remote debugging, the program output is displayed on the target system. You can also redirect the output of the application to a log file.
The same program run locally would look like this:
$ ladebug /work/test/hello
Welcome to the Ladebug Debugger Version 3.0
------------------
object file name: /usr/users/dss/work/test/hello
Reading symbolic information ...done
(ladebug) stop in main; run
[#1: stop in main ]
s[1] stopped at [main:6 0x120001fa0]
6 (void) printf("Hello, world !\n");
(ladebug) cont
Hello, world !
Thread has finished executing
(ladebug)
|
The debugger quit command ends the remote debugger session and automatically disconnects from the server.
The quit command does not terminate the process running on the target system. Use the kill command to terminate a running process and end the remote debugger session. |
16.5 Command-Line Options for Remote Debugging
Table 16-2 lists the debugger command-line options that support
remote debugging.
| Option/Qualifier | Meaning/Conditions |
|---|---|
| -rn 1 node_or_address [, udp_port 2 ] | Specifies the internet node name or IP address of the machine on which the remote debugger server is running (that is, the node running the program to be debugged); optionally specifies the UDP port on which to connect the server. Either the node name or IP address is required; there is no default. |
| -pid process_id | Specifies the process ID of the process to be debugged. When you specify this option, Ladebug debugs a running process rather than loading a new process. |
| -rfn 1 arbitrary_string | Specifies the file name (or other identifier) of the image to be loaded on a remote system. This option defaults to the local image file name and it is passed to the remote system uninterpreted. Use only with -rn ; do not combine with -pid . |
| -rinsist | Connects to a running remote process using the connect insist protocol message instead of the connect protocol message. This option functions as a request to the server to connect to the client, even if another client is already connected. (The previously connected client is disconnected.) Use only with with -rn and -pid . |
| -ru username | Specifies the user name to be used on the remote system. The default is the local user name. |
The following examples show how to use the remote debugger command-line options.
Example 1
$ ladebug -rn 1.2.3.4 -ru brown program1 |
Connects to the server on the node with IP address 1.2.3.4 and asks the server to load a process called program1. The local copy of the object file is also called program1. The user name on the remote node is brown.
Example 2
$ ladebug -rn EB64 -rfn '**process name A**' program3 |
Connects to the server on the node with IP name EB64 and asks it to load the process called '**process name A**'. The local object file is called program3.
| Previous | Next | Contents | Index |