Free Pascal supports debug information for the GNU debugger gdb, or it's derivatives Insight on win32 or ddd on LINUX.
This chapter describes shortly how to use this feature. It doesn't attempt to describe completely the GNU debugger, however. For more information on the workings of the GNU debugger, see the gdb users' guide.
Free Pascal also suports gprof, the GNU profiler, see section for more information on profiling.
To compile a program with debugging support, just specify the -g option on the command-line, as follows:
ppc386 -g hello.ppThis will generate debugging information in the executable from your program. You will notice that the size of the executable increases substantially because of this9.1.
Note that the above will only generate debug information for the code that has been generated when compiling hello.pp. This means that if you used some units (the system unit, for instance) which were not compiled with debugging support, no debugging support will be available for the code in these units.
There are 2 solutions for this problem.
If all went well, the executable now contains the necessary information with which you can debug it using GNU gdb.
To use gdb to debug your program, you can start the debugger, and give it as an option the full name of your program:
gdb helloOr, under DOS:
gdb hello.exe
This starts the debugger, and the debugger immediately loads your program into memory, but it does not run the program yet. Instead, you are presented with the following (more or less) message, followed by the gdb prompt '(gdb)':
GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details. GDB 4.15.1 (i486-slackware-linux), Copyright 1995 Free Software Foundation, Inc... (gdb)To start the program you can use the run command. You can optionally specify command-line parameters, which will then be fed to your program, for example:
(gdb) run -option -anotheroption needed_argumentIf your program runs without problems, gdb will inform you of this, and return the exit code of your program. If the exit code was zero, then the message 'Program exited normally'.
If something went wrong (a segmentation fault or so), gdb will stop the execution of your program, and inform you of this with an appropriate message. You can then use the other gdb commands to see what happened. Alternatively, you can instruct gdb to stop at a certain point in your program, with the break command.
Here is a short list of gdb commands, which you are likely to need when debugging your program:
Remark: My copy of gdb needs '.' to be added explicitly to the search path, otherwise it doesn't find the sources.
for more information, see the gdb users' guide, or use the 'help' function in gdb.
The appendix contains a sample init file for gdb, which produces good results when debugging Free Pascal programs.
It is also possible to use RHIDE, a text-based IDE that uses gdb. There is a version of RHIDE available that can work together with FPC.
There are some peculiarities of Free Pascal which you should be aware of when using gdb. We list the main ones here:
As an example, of you want to watch the value of a loop variable count, you should type
watch COUNTOr if you want stop when a certain function (e.g MyFunction) is called, type
break MYFUNCTION
You can also use the following user function to print strings:
define pst set $pos=&$arg0 set $strlen = {byte}$pos print {char}&$arg0.st@($strlen+1) end document pst Print out a Pascal string endIf you insert it in your gdb.ini file, you can look at a string with this function. There is a sample gdb.ini in appendix .
For example, the method TPoint.Draw would be converted to TPOINT__DRAW, and could be stopped at with
break TPOINT__DRAW
You can compile your programs with profiling support. for this, you just have to use the compiler switch -pg. The compiler wil insert the necessary stuff for profiling.
When you have done this, you can run your program as you normally would run it.
yourexeWhere yourexe is the name of your executable.
When your program finishes a file called gmon.out is generated. Then you can start the profiler to see the output. You can better redirect the output to a file, becuase it could be quite a lot:
gprof yourexe > profile.log
Hint: you can use the -flat option to reduce the amount of output of gprof. It will then only output the information about the timings
For more information on the GNU profiler gprof, see its manual.
The unit that does this is called heaptrc. If you want to use it, you should include it as the first unit in you uses clause. Alternatively, you can supply the -gh switch to the compiler, and it will include the unit automatically for you.
After the program exits, you will get a report looking like this:
Marked memory at 0040FA50 invalid Wrong size : 128 allocated 64 freed 0x00408708 0x0040CB49 0x0040C481 Call trace for block 0x0040FA50 size 128 0x0040CB3D 0x0040C481The output of the heaptrc unit is customizable by setting some variables.
You can find more information about the usage of the heaptrc unit in the Unit reference.
Normally, when a run-time error occurs, you are presented with a list of addresses that represent the call stack backtrace, i.e. the addresses of all procedures that were invoked when the run-time error occurred.
This list is not very informative, so there exists a unit that generates the file names and line numbers of the called procedures using the addresses of the stack backtrace. This unit is called lineinfo.
You can use this unit by giving the -gl option to the compiler. The unit will be automatically included. It is also possible to use the unit explicitly in your uses clause, but you must make sure that you compile your program with debug info.
Here is an example program:
program testline; procedure generateerror255; begin runerror(255); end; procedure generateanerror; begin generateerror255; end; begin generateanerror; end.When compiled with -gl, the following output is generated:
Runtime error 255 at 0x0040BDE5 0x0040BDE5 GENERATEERROR255, line 6 of testline.pp 0x0040BDF0 GENERATEANERROR, line 13 of testline.pp 0x0040BE0C main, line 17 of testline.pp 0x0040B7B1Which is more understandable than the normal message. Make sure that all units you use are compiled with debug info, because if they are not, no line number and filename can be found.
If you combine the lineinfo and the heaptrc information, then the output of the heaptrc unit will contain the names of the files and line numbers of the procedures that occur in the stack backtrace.
In such a case, the output will look something like this:
Marked memory at 00410DA0 invalid Wrong size : 128 allocated 64 freed 0x004094B8 0x0040D8F9 main, line 25 of heapex.pp 0x0040D231 Call trace for block 0x00410DA0 size 128 0x0040D8ED main, line 23 of heapex.pp 0x0040D231If lines without filename/line-number occur, this means there is a unit which has no debug info included. (in the above case, the getmem call itself)