| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
For debugging your programs you need now no external debugger, because RHIDE has one integrated. The integrated debugger is not code which I have written, but it is GDB 4.16, which is linked in RHIDE.
Because RHIDE uses a special method to communicate with GDB it is currently not possible to use all of the features, which GDB has. I have implemented at this time the most important functions, which are needed to debug your program. So it is not possible to give GDB the same commands as when running GDB stand alone. That means, if you need any very special feature of GDB you must run GDB.
The integrated debugger is a real source level debugger like GDB. If you step through your program you will see every time exactly where in the sources you are. But to use the ability to debug your program needs, that you have compiled your source files with debugging information and these symbols must not have been stripped from the executable.
5.1 Limitations of the integrated debugger 5.2 Dual display debugging 5.3 Using the integrated debugger 5.4 Problems with C++ programs 5.5 Using Breakpoints
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Because the integrated debugger is GDB, you will have all the limitations which GDB has in addition to well known DJGPP and/or MS-DOS limitations. Here is a (not complete) list of known misfeatures:
/* This is an example, that GCC produces wrong line number
information for code which is optimized out. (compile this
with -O) */
int a = 1;
int b = 2;
int main()
{
if (a == b) return 0;
if ((a + 1) == b) return 1;
return 0; /* The debugger should never come here,
but it comes */
}
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
With this debugging technique you will get the best debugging results especially when debugging graphics programs.
To use the dual display with RHGDB use the `-D' switch for RHGDB.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If you are familiar with Borland's debugger, you will see, that most of the functions of that debugger are implemented in the same or in a similar way (this includes the key bindings).
5.3.1 Stepping through the source code 5.3.2 Evaluating the contents of variables 5.3.3 Watching the contents of variables
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
For stepping through your code, there are three ways. This is at first the Step-function F8. With this you execute a complete source line. If there is a function call at the current execution point, this function is called without debugging it. This technique is the same like the `next'-command from GDB.
The next way is the Trace-function. It is like the Step-function, F7, except that if there is a function call at the current execution point, you will go into this function when there is debugging information for that function available. This technique is the same as the `step'-command from GDB.
And the third way is the Goto-Cursor-function. For this, move the cursor to the line in your source code and press F4. Now the execution of your program is continued until it comes to that line. Sometimes you will get an error message, that for the specified line is no code generated. This comes from the optimization of your code by GCC. In this case try a line below or above.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
You can evaluate also the the contents of variables, when your program has been started. For this you can press Ctrl+F4 and you will see a dialog, where you can type in the expression to evaluate, a line with the result and a line, where you can give the expression a new value. If you have pressed this in an editor window, RHIDE tries to find the word under the cursor and copies this as default in the expression input line. To get the contents of this expression you have to press the Evaluate-button.
If the expression could not be evaluated so it is shown in the result line. For the exact syntax of getting the contents of an expression see section `Expressions' in gdb. You can also show the value of the expression in several formats see section `Output Formats' in gdb.
In addition to the functionality of the Borland debuggers, GDB (and of course also RHIDE) can evaluate the result of function calls. If you have, for example, in your debugged program a function
int foo(int arg1)
{
/* do something and return a value */
}
|
foo(16) |
16. As arguments you can also use
any known variable or complex expressions.
A known limitation is, that the expressions are NOT checked for validity. That means, you can produce any exception there, which will terminate your program. As an example type in the expression input line
3/0 |
As an special side effect you can use this also as a calculator. You can evaluate any trivial or complex expression and this is also available, if you haven't started the integrated debugger.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Within the watch window you can press Enter on an expression to change that expression (NOT the contents of that expression) or you can press Del to remove the variable from the watch window.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
For accessing the member of a baseclass you must do some tricks. Let me explain it on an example:
class A
{
public:
int a;
};
class B : public A
{
public:
void test();
};
void B::test()
{
fprintf(stdout,"%d\n",a);
}
|
If you debug the program in the function B::test() and you
want to get the contents of the member a, you have to access
it with this->A.a !!! That means: At first you must access
all members with the implicit this variable and at second
you must give all baseclasses until that, where the member was
declared.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
5.5.1 Setting a breakpoint 5.5.2 Modifying and setting a breakpoint 5.5.3 Problems with breakpoints
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In the breakpoint dialog you can also set or delete a breakpoint with the given buttons. If you want to set a new breakpoint, use the New-Button. Then you will get a dialog which you also get when you press the Modify-Button. In this dialog you can change many things of the breakpoint.
In this dialog is the only point for setting a breakpoint at a specified function. For doing this you must set at first the type of the breakpoint to Function. Then you can type in the function input line the name of the function or hit Ctrl+F1 to get a list of functions which are available from where you can select one with Enter.
For setting a breakpoint at a specified line, set the breakpoint type to Line and type in the filename and the linenumber.
The next what you can modify on a breakpoint is a condition. That means that the breakpoint should stop your program only, if the condition is true. Write the condition in the programming language of your source file and you can use any accessible variable and you can call also functions of the debugged program. For other information about the syntax see section `Conditions' in gdb.
And at last you can give your breakpoints also a count. A breakpoint count is a number, how often this breakpoint is ignored. That means, if you type there, for example, 10, then the RHIDE stops the execution of the program only, if it comes to that point the tenth time. WARNING: This count is set by RHIDE only once. After the breakpoint is really hit, from now on the breakpoint stops your program every time, the breakpoint is reached.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |