| Title and Contents |
-g switch.
If the problem only occurs in optimized code, use the -g3 switch.
% stty rows 47 ; setenv LINES 47 % stty cols 80 ; setenv COLS 80Following are four basic alternatives for running the debugger on a process:
% ladebug a.out
Welcome to the Ladebug Debugger Version 4.0-58
------------------
object file name: /usr/users/user1/a.out
Reading symbolic information ...done
(ladebug) stop in main
[#1: stop in int main(void) ]
(ladebug) run
% ladebug
Welcome to the Ladebug Debugger Version 4.0-58
(ladebug) load a.out
Reading symbolic information ...done
(ladebug) stop in main
[#1: stop in int main(void) ]
(ladebug) run
% a.out &
[2] 27859
% jobs
[2] Running
...
% ladebug a.out -pid 27859
Attached to process id 27859
....
Press Ctrl/C to interrupt the process.
% a.out &
[2] 27859
% jobs
[2] Running
...
% ladebug
(ladebug) attach 27859 a.out
Attached to process id 27859
....
Press Ctrl/C to interrupt the process.
NOTE: In the case of Fortran, routine main at which your
program stops is not your main program unit. Rather, it is a main routine
supplied by the Fortran system that performs some initialization and then
calls your code. Just step forward a couple of times (probably twice) and
you will soon step into your code.
(ladebug) you type here
When you enter commands, you use the left and right arrow keys to move within the line and the up and down arrow keys to recall previous commands for editing. When you finish entering a command, press the Enter key to submit the completed line to the debugger for processing.
You can continue a line by ending the line to be continued with a backslash (\) character.
On a blank line, press the Enter key to re-execute the most recent valid command.
Following are two very useful commands:
(ladebug) help (ladebug) quit
source
command as follows:
(ladebug) source filenameThe
source command causes the debugger to read and execute
Ladebug commands from
filename.
Processes contain one or more threads of execution. The threads execute functions. Functions are sequences of instructions that come from source lines within source files.
As you enter debugger commands to manipulate your process, it would be very tedious to have to repeatedly specify which thread, source file, and so on you wish the command to be applied to. To prevent this, each time the debugger stops the process, it re-establishes a static context and a dynamic context for your commands. The components of the static context are independent of this run of your program; the components of the dynamic context are dependent on this run.
You can change most of these individually to point to other instances, as described in the relevant portions of this manual, and the debugger will modify the rest of the static and dynamic context to keep the various components consistent.
After you specify the program (either on the shell command line or
by using the load command), but before you have requested the debugger to
create the process, you can still do things that seem to require a running
process, for example, you can create breakpoints and examine sources. Any breakpoints
that you create will be inserted into the process as soon as possible after it
executes your program.
To have the debugger create a process (rather than attach to an existing process), you request it to run, specifying, if necessary, any input and output redirection and arguments as follows:
% ladebug a.out
Welcome to the Ladebug Debugger Version 4.0-58
(ladebug) run
or
(ladebug) run args
or
(ladebug) run > output-file
or
(ladebug) run args > output-file < input-fileThe result of using any of the preceding command variations is similar to having attached to a running process. The rerun command repeats the previous run command with the same arguments and files.
(ladebug) run
^C
Interrupt (for process)
Stopping process localhost:27903 (a.out).
Thread received signal INT
stopped at [int main(int):5 0x120001138]
5 while (argc < 2 && i < 10000000)
(ladebug) run
Thread received signal SEGV
stopped at [void buggy(char*, char*):13 0x120001ba4]
13 output[k] = input[k];
(ladebug) stop in main
[#1: stop in int main(void) ]
(ladebug) run
[1] stopped at [int main(void):182 0x1200023f8]
182 List<Node> nodeList;
(ladebug) watch variable nodeList._firstNode write
[#2: watch variable nodeList._firstNode 0x11fffeb48, 0x11fffeb4f write ]
(ladebug) cont
[2] Address 0x11fffeb48 was accessed at:
List<Node>::List(void): x_list.cxx
[line 121, 0x120001d74] stq r31, 0(r1)
0x11fffeb48: Old value = 0xfffffffffffffff8
0x11fffeb48: New value = 0x0000000000000000
[2] stopped at [List<Node>::List(void):123 0x120001d78]
123 }
/ command to search for a string:
% ladebug a.out
(ladebug) file
x_list.cxx
(ladebug) list 180: 10
180 main()
181 {
182 List<Node> nodeList;
183
184 // add entries to list
185 //
> 186 IntNode* newNode = new IntNode(1);
187 nodeList.append(newNode);
188
189 CompoundNode* cNode = new CompoundNode(12.345, 2);
(ladebug) /CompoundNode
197 CompoundNode* cNode2 = new CompoundNode(10.123, 5);
Aliases are shorthand forms of longer commands.
This example shows using the W alias, which lists up to 20 lines
around the current line. Note that a right bracket (>) marks the current line.
(ladebug) alias W
W list $curline - 10:20
(ladebug) W
176
177
178 // The driver for this test
179 //
180 main()
181 {
182 List<Node> nodeList;
183
184 // add entries to list
185 //
> 186 IntNode* newNode = new IntNode(1);
187 nodeList.append(newNode);
188
189 CompoundNode* cNode = new CompoundNode(12.345, 2);
190 nodeList.append(cNode);
191
192 nodeList.append(new IntNode(3));
193
194 IntNode* newNode2 = new IntNode(4);
195 nodeList.append(newNode2);
(ladebug) thread
Thread Name State Substate Policy Pri
------ ------------------------- --------------- ----------- ------------ ---
>* 2 <anonymous> running SCHED_OTHER 19
(ladebug) show thread
Thread Name State Substate Policy Pri
------ ------------------------- --------------- ----------- ------------ ---
1 default thread running SCHED_OTHER 19
-1 manager thread blk SCS SCHED_RR 19
-2 null thread for VP 0 ready new null thread 0
-3 null thread for VP 1 ready null thread 0
-4 null thread for VP 0 ready new null thread 0
-5 null thread for VP 0 ready new null thread 0
>* 2 <anonymous> running SCHED_OTHER 19
You can select any thread to be the focus of commands that show things. For example:
(ladebug) thread 1
Thread Name State Substate Policy Pri
------ ------------------------- --------------- ----------- ------------ ---
> 1 default thread running SCHED_OTHER 19
(ladebug) where 4
>0 0x12000224c in ((Node*)0x140002000)->Node::Node() "x_list.cxx":77
#1 0x120002298 in ((IntNode*)0x140002000)->IntNode::IntNode(data=2) "x_list.cxx":88
#2 0x120002338 in ((CompoundNode*)0x140002000)->CompoundNode::CompoundNode(fdata=12.34500026702881, idata=2) "x_list.cxx":101
#3 0x1200024fc in main() "x_list.cxx":189
(ladebug) up 2
>2 0x120002338 in ((CompoundNode*)0x140002000)->CompoundNode::CompoundNode(fdata=12.34500026702881, idata=2) "x_list.cxx":101
101 CompoundNode::CompoundNode(float fdata, int idata)
(ladebug) list $curline - 10: 20
91 void IntNode::printNodeData() const
92 {
93 cout << " type is integer, value is ";
94 cout << _data << endl;
95 }
96
97
98 //=============================================================================
99 // CompoundNode definition
100 //
> 101 CompoundNode::CompoundNode(float fdata, int idata)
102 :
103 IntNode(idata),
104 _fdata (fdata)
105 {
106 }
107 void CompoundNode::printNodeData() const
108 {
109 cout << " type is compound, value is ";
110 cout << _fdata << endl;
(ladebug) down 1
>1 0x120002298 in ((IntNode*)0x140002000)->IntNode::IntNode(data=2) "x_list.cxx":88
88 IntNode::IntNode(int data) : _data(data)
(ladebug) print fdata
12.34500026702881
(ladebug) print idata
2
(ladebug) print idata + 59
61
(ladebug) print this
0x140002000
(ladebug) print *this
class CompoundNode {
_fdata = 0;
_data = 0; // class IntNode
_nextNode = 0x0; // class IntNode::Node
}
(ladebug) run
Thread received signal SEGV
stopped at [void buggy(char*, char*):13 0x120001ba4]
13 output[k] = input[k];
(ladebug) ($curpc - 20)/10i
CompoundNode::CompoundNode(float, int): x_list.cxx
[line 105, 0x120002328] cpys $f17,$f17,$f0
[line 105, 0x12000232c] bis r31, r18, r8
[line 101, 0x120002330] bis r31, r19, r16
[line 101, 0x120002334] bis r31, r8, r17
[line 101, 0x120002338] bsr r26, IntNode::IntNode(int)
*[line 101, 0x12000233c] ldq r18, -32712(gp)
[line 101, 0x120002340] lda r18, 48(r18)
[line 101, 0x120002344] stq r18, 8(r19)
[line 101, 0x120002348] sts $f0, 24(r19)
[line 106, 0x12000234c] bis r31, r19, r0
(ladebug) alias wi
wi ($curpc - 20)/10 i
(ladebug) $pc/10x
0x12000233c: 8038 a65d 0030 2252 0008 b653 0018 9813
0x12000234c: 0400 47f3
(ladebug) $pc/6xx
0x12000233c: a65d8038 22520030 b6530008 98130018
0x12000234c: 47f30400 47f5041a
(ladebug) $pc/2X
0x12000233c: 22520030a65d8038 98130018b6530008
You can examine registers. For example:
(ladebug) print $r16
5368717312
(ladebug) px $r16
0x140002000
(ladebug) alias px
px printx
(ladebug) printregs
$r0 [$v0] = 1 $r1 [$t0] = 5368717312
$r2 [$t1] = 4 $r3 [$t2] = 3
$r4 [$t3] = 2 $r5 [$t4] = 5368717312
$r6 [$t5] = 0 $r7 [$t6] = 4831847228
$r8 [$t7] = 2 $r9 [$s0] = 342189472
$r10 [$s1] = 0 $r11 [$s2] = 4096
$r12 [$s3] = 351003456 $r13 [$s4] = 4096
$r14 [$s5] = 340581568 $r15 [$s6] = 1
$r16 [$a0] = 5368717312 $r17 [$a1] = 2
$r18 [$a2] = 2 $r19 [$a3] = 5368717312
$r20 [$a4] = 5368717360 $r21 [$a5] = 4831847680
$r22 [$t8] = 1 $r23 [$t9] = 544
$r24 [$t10] = 4396973371008 $r25 [$t11] = 1
$r26 [$ra] = 4831847228 $r27 [$t12] = 0
$r28 [$at] = 4831845184 $r29 [$gp] = 5368742704
$r30 [$sp] = 4831834608 $r31 [$zero]= 0
$f0 = 12.34500026702881 $f1 = 0
$f2 = 0 $f3 = 0
$f4 = 0 $f5 = 0
$f6 = 0 $f7 = 0
$f8 = 0 $f9 = 0
$f10 = 0 $f11 = 1.667281912556707e-315
$f12 = 0.1 $f13 = 0
$f14 = 2.035550460865936e-320 $f15 = 1.513249931733528e-315
$f16 = 1.703760913552757e-315 $f17 = 12.34500026702881
$f18 = 0 $f19 = 3.006903935382313e-315
$f20 = 1.742030250348328e-315 $f21 = 1.491998330381693e-315
$f22 = 3.005128006537023e-315 $f23 = 1.519175201736224e-315
$f24 = 1.742030250348328e-315 $f25 = 1.519184766847128e-315
$f26 = 4.940656458412465e-324 $f27 = 0
$f28 = 1.742030250348328e-315 $f29 = 3.004529238499515e-315
$f30 = 1.742030250348328e-315 $f31 = 0
$pc = 0x12000233c $ps = 0x8
$fpcr = 0x800000000000000 $vfp = 0x11ffff1f0
| Continue until another interesting thing happens |
c
|
cont
|
|
| Single step by line, but step over calls |
n
|
next
|
|
| Single step to a new line, stepping into calls |
s
|
step
|
|
| Continue until control returns to the caller |
return
|
|
|
| Single step by instruction, over calls | ni |
nexti
|
|
| Single step by instruction, into calls |
si
|
stepi
|
|
The following example demonstrates stepping through lines of source code.
(ladebug) list $curline - 10: 20
172
173 if (i == 1) cout << "The list is empty ";
174 cout << endl << endl;
175 }
176
177
178 // The driver for this test
179 //
180 main()
181 {
> 182 List<Node> nodeList;
183
184 // add entries to list
185 //
186 IntNode* newNode = new IntNode(1);
187 nodeList.append(newNode);
188
189 CompoundNode* cNode = new CompoundNode(12.345, 2);
190 nodeList.append(cNode);
191
(ladebug) next
stopped at [int main(void):186 0x120002420]
186 IntNode* newNode = new IntNode(1);
(ladebug) next 7
stopped at [int main(void):197 0x12000265c]
197 CompoundNode* cNode2 = new CompoundNode(10.123, 5);
(ladebug) step
stopped at [CompoundNode::CompoundNode(float, int):101 0x120002330]
101 CompoundNode::CompoundNode(float fdata, int idata)
(ladebug) list $curline - 2: 6
99 // CompoundNode definition
100 //
> 101 CompoundNode::CompoundNode(float fdata, int idata)
102 :
103 IntNode(idata),
104 _fdata (fdata)
(ladebug) step
stopped at [IntNode::IntNode(int):88 0x120002294]
88 IntNode::IntNode(int data) : _data(data)
(ladebug) list $curline - 2: 5
86 // IntNode definition
87 //
> 88 IntNode::IntNode(int data) : _data(data)
89 {
90 }
(ladebug) return
stopped at [CompoundNode::CompoundNode(float, int):101 0x12000233c]
101 CompoundNode::CompoundNode(float fdata, int idata)
(ladebug) return
stopped at [int main(void):197 0x1200026ac]
197 CompoundNode* cNode2 = new CompoundNode(10.123, 5);
(ladebug) step
stopped at [int main(void):198 0x1200026dc]
198 nodeList.append(cNode2);
(ladebug) step
stopped at [void List<Node>::append(class Node* const):148 0x120001d9c]
148 if (!_firstNode)
(ladebug) list $curline: 8
> 148 if (!_firstNode)
149 _firstNode = node;
150 else {
151 Node* currentNode = _firstNode;
152 while (currentNode->getNextNode())
153 currentNode = currentNode->getNextNode();
154 currentNode->setNextNode(node);
155 }
(ladebug) step 2
stopped at [void List<Node>::append(class Node* const):152 0x120001dc0]
152 while (currentNode->getNextNode())
The following example demonstrates stepping at the instruction level:
(ladebug) $curpc - 20/14i
void List<Node>::append(class Node* const): x_list.cxx
[line 149, 0x120001dac] ldq r3, 24(sp)
[line 149, 0x120001db0] stq r2, 0(r3)
[line 149, 0x120001db4] br r31, 0x120001e0c
[line 151, 0x120001db8] ldq r4, 24(sp)
[line 151, 0x120001dbc] ldq r9, 0(r4)
*[line 152, 0x120001dc0] bis r31, r9, r16
[line 152, 0x120001dc4] ldq r27, -32584(gp)
[line 152, 0x120001dc8] jsr r26, (r27), Node::getNextNode
[line 152, 0x120001dcc] ldah gp, 8192(r26)
[line 152, 0x120001dd0] lda gp, 25956(gp)
[line 152, 0x120001dd4] beq r0, 0x120001df4
[line 153, 0x120001dd8] bis r31, r9, r16
[line 153, 0x120001ddc] ldq r27, -32584(gp)
[line 153, 0x120001de0] jsr r26, (r27), Node::getNextNode
(ladebug) stepi
stopped at [void List<Node>::append(class Node* const):152 0x120001dc4] ldq r27, -32584(gp)
(ladebug) nexti
stopped at [void List<Node>::append(class Node* const):152 0x120001dc8] jsr r26, (r27), Node::getNextNode
(ladebug) stepi
stopped at [class Node* Node::getNextNode(void):81 0x120002264] bis r31, r16, r1
(ladebug) return
stopped at [void List<Node>::append(class Node* const):152 0x120001dcc]
152 while (currentNode->getNextNode())
(ladebug) nexti 2
stopped at [void List<Node>::append(class Node* const):152 0x120001dd4] beq r0, 0x120001df4
In a program that does not use multiple threads, you can use snapshots to save your state before you step over the call. Then clone that snapshot to position another process just before the call so you can step into it.
The following example shows the stages of a snapshot being used in this way:
(ladebug) next 2
stopped at [int main(void):187 0x120002498]
187 nodeList.append(newNode);
(ladebug) list $curline - 10: 20
177
178 // The driver for this test
179 //
180 main()
181 {
182 List<Node> nodeList;
183
184 // add entries to list
185 //
186 IntNode* newNode = new IntNode(1);
> 187 nodeList.append(newNode);
188
189 CompoundNode* cNode = new CompoundNode(12.345, 2);
190 nodeList.append(cNode);
191
192 nodeList.append(new IntNode(3));
193
194 IntNode* newNode2 = new IntNode(4);
195 nodeList.append(newNode2);
196
(ladebug) save snapshot
# 1 saved at 00:19:24 (PID: 23771).
stopped at [int main(void):187 0x120002498]
187 nodeList.append(newNode);
(ladebug) next
stopped at [int main(void):189 0x1200024b0]
189 CompoundNode* cNode = new CompoundNode(12.345, 2);
(ladebug) list $curline - 10: 20
179 //
180 main()
181 {
182 List<Node> nodeList;
183
184 // add entries to list
185 //
186 IntNode* newNode = new IntNode(1);
187 nodeList.append(newNode);
188
> 189 CompoundNode* cNode = new CompoundNode(12.345, 2);
190 nodeList.append(cNode);
191
192 nodeList.append(new IntNode(3));
193
194 IntNode* newNode2 = new IntNode(4);
195 nodeList.append(newNode2);
196
197 CompoundNode* cNode2 = new CompoundNode(10.123, 5);
198 nodeList.append(cNode2);
(ladebug) clone snapshot
Process has exited
Process 26917 cloned from Snapshot 1.
# 1 saved at 00:19:24 (PID: 23771).
stopped at [int main(void):187 0x120002498]
187 nodeList.append(newNode);
NOTE: fork() was used by the debugger both to create the
snapshot and to clone it.
(ladebug) list $curline - 10: 20
177
178 // The driver for this test
179 //
180 main()
181 {
182 List<Node> nodeList;
183
184 // add entries to list
185 //
186 IntNode* newNode = new IntNode(1);
> 187 nodeList.append(newNode);
188
189 CompoundNode* cNode = new CompoundNode(12.345, 2);
190 nodeList.append(cNode);
191
192 nodeList.append(new IntNode(3));
193
194 IntNode* newNode2 = new IntNode(4);
195 nodeList.append(newNode2);
196