Debug

For developers writing C++, Fortran, Java, code who have questions or comments to make.

Moderators: silvia, selimgunay, Moderators

Post Reply
brag006
Posts: 173
Joined: Wed Feb 15, 2012 1:26 pm
Location: University of Auckland

Debug

Post by brag006 » Tue Jan 07, 2014 11:53 am

I am trying to compile a debug version but I am getting an error in Domain.cpp in the pressure constraint.

bool
Domain::addPressure_Constraint(Pressure_Constraint *pConstraint)
{
#ifdef _G3DEBUG
// check the Node exists in the Domain
int nodeTag = pConstraint->getNodeConstrained();
Node *nodePtr = this->getNode(nodeTag);
if (nodePtr == 0) {
opserr << "Domain::addPressure_Constraint - cannot add as node with tag";
opserr << nodeTag << "does not exist in model\n";
return false;
}
#endif

It appears that Pressure_Constraint does not have a member function called getNodeConstrained. There was a private member called findNodeTag. I tried moving the member to public and then changed the line to as follows:
int nodeTag = pConstraint->findNodeTag();

But I need to pass the domain to this function. I didn't know how to do that.

brag006
Posts: 173
Joined: Wed Feb 15, 2012 1:26 pm
Location: University of Auckland

Re: Debug

Post by brag006 » Tue Jan 07, 2014 1:16 pm

It seems to have worked with this line:

int nodeTag = pConstraint->findNodeTag(this);

Is this a bug that needs to be fixed?

mhscott
Posts: 586
Joined: Tue Jul 06, 2004 3:38 pm
Location: Corvallis, Oregon USA
Contact:

Re: Debug

Post by mhscott » Wed Jan 08, 2014 9:24 am

Yes, it is fixed now. We've been compiling without _G3DEBUG defined, so never noticed. Thanks!

johnys
Posts: 3
Joined: Sat Apr 23, 2016 4:10 pm

Re: Debug

Post by johnys » Sat Apr 23, 2016 4:21 pm

Download the sample program broken.cpp
Compile the program and execute the program.
% g++ -g broken.cpp -o broken
% ./broken
Whatever the input, the output will be inf. The -g option is important because it enables meaningful GDB debugging.
Start the debugger
% gdb broken
This only starts the debugger; it does not start running the program in the debugger.
Look at the source code and set a breakpoint at line 43
(gdb) b 43
which is
double seriesValue = ComputeSeriesValue(x, n);
Now, we start to run the program in the debugger.
(gdb) run
Note: If you need to supply the command-line arguments for the execution of the program, simply include them after the run command, just as normally done on the command line.
The program starts running and asks us for the input.
Let's enter the values as x=2 and n=3. The expected output value is 5. The following is a snapshot of the program running in the debugger:
This program is used to compute the value of the following series :
(x^0)/0! + (x^1)/1! + (x^2)/2! + (x^3)/3! + (x^4)/4! + ........ + (x^n)/n!
Please enter the value of x : 2

Please enter an integer value for n : 3


Breakpoint 1, main () at broken.cpp:43
43 double seriesValue = ComputeSeriesValue(x, n);
Note that the program execution stopped at our first (and only) breakpoint.
Step into the ComputeSeriesValue() function
To step into a function call, we use the following command:
(gdb) step
ComputeSeriesValue (x=2, n=3) at broken.cpp:17
17 double seriesValue=0.0;
At this point, the program control is at the first statement of the function ComputeSeriesValue (x=2, n=3)
Next let's step through the program until we get into ComputeFactorial.
(gdb) next
18 double xpow=1;
(gdb) n
20 for (int k = 0; k <= n; k++) {
(gdb)
21 seriesValue += xpow / ComputeFactorial(k) ;
(gdb) s
ComputeFactorial (number=0) at broken.cpp:7
7 int fact=0;
Here we use the next command, which is similar to step except it will step over (instead of into) functions. The distinction doesn't matter here since there are no functions. You may use the shortest, unambigious spelling of a GDB command to save some typing. Here we use n and s instead of next and step, respectively. If the command is simply a repeat of the previous command, you can just hit return, which will execute the last command. Finally, we step (with s) into ComputeFactorial(). (If we'd used next, it would have stepped over ComputeFactorial.)
Where are we?
If you want to know where you are in the program's execution (and how, to some extent, you got there), you can view the contents of the stack using the backtrace command as follows:
(gdb) bt
#0 ComputeFactorial (number=0) at broken.cpp:7
#1 0x08048907 in ComputeSeriesValue (x=3, n=2) at broken.cpp:21
#2 0x08048a31 in main () at broken.cpp:43
Watching changes We can step through the program and examine the values using the print command.
(gdb) n
9 for (int j = 0; j <= number; j++) {
(gdb) n
10 fact = fact * j;
(gdb) n
9 for (int j = 0; j <= number; j++) {
(gdb) print fact
$2 = 0
(gdb) n
13 return fact;
(gdb) quit
The print command (abbreviated p) reveals that the value of fact never changes. Note that the function is returning a value of 0 for the function call ComputeFactorial(number=0). This is an ERROR!
By taking a closer look at the values printed above, we realize that we are computing fact=fact * j where fact has been initialized to 0; fact should have been initialized to 1. We quit GDB with the quit command. Next we need to change the following line:

int fact = 1;
Recompile the code and run it, you will get the expected output.

Post Reply