lab5

PARAMETER STATEMENT, EXPLICIT INTERFACE, MODULES AND THE IDB DEBUGGER

NOTE: for all lab and projects create the proper directories and subdirectories !!!

REMINDER FOR THOSE WHO ARE NOT LISTENING

All projects in aero 361 need to follow a strict layout. The purpose of the layout is to organize the work and mitigate clutter when the projects become big --- specially when reports are involved. The reports will be written in LaTex which is basically writing code! The projects will also emphasize post processing from using Matlab, Tecplot and Xmgrace. Thus a single project will consist of source codes in f90, latex source codes, data from the f90 code and tecplot or matlab figures. All these various items will have to be placed in separate directories so that clutter and confusion is minimized and efficiency is maximized: your first lesson in OPTIMIZATION. The figure below illustrates the directory structure for proj[#] or lab[#]. All other projects will follow the same procedure and layout.

/home/joeusr

aero361/

labs

lab5


src/     dat/       bin/  report/

PARAMETER STATEMENT

When dynamic allocation was not available in f77 a named variable constant had to be initialized in order allocate space for arrays. The extent of the arrays was fixed by this named variable constant. The program could allocate arrays up to and less than that set by the named variable constant. A named variable constant in short is a PARAMETER, where its value cannot be changed. It can be a real or an integer

Integer,parameter :: n=100
Integer,parameter :: ndmin = 10
real(kind=8),parameter :: eps = 1.0e-7

PROGRAM WITH PARAMETER STATEMENTS TO DEFINE ARRAY BOUNDS

Write the code below and call it main_param.f90 and run the code. Then edit the code such that
  • n=100000
  • m=100000
  • l=200000
When you compile the code with the above dimensions an error message regarding insufficient memory should appear as shown below

Error 530 : In program unit MAIN the size of array Z exceeds the implementation limit (2**31-1)
Error 530 : In program unit MAIN the size of array Y exceeds the implementation limit (2**31-1)
Error 530 : In program unit MAIN the size of array X exceeds the implementation limit (2**31-1)


program main
	implicit none
integer,parameter::dp=8
integer,parameter::n=10
integer,parameter::m=10
integer,parameter::l=10
integer :: i,j,k
real(kind=dp),dimension(1:n,1:m,1:l):: x,y,z ! locally defined explicit shape array from
! parameters defined.
do k = 1,l
do j=1,m
do i=1,n
x(i,j,k)=float(i)*float(j)*float(k)
y(i,j,k)=float(i)*float(j)*float(k)
z(i,j,k)=float(i)*float(j)*float(k)

write(6,'(3f30.16,1x)')x(i,j,k), y(i,j,k),z(i,j,k)
enddo
enddo
enddo
end program main

PROGRAM WITH ALLOCATBLE STATEMENTS TO DEFINE ARRAY BOUNDS

Write the code shown in this section below and name it main_allc.f90. Make sure there is an input.dat file in the iof directory from which the dimensions of the arrays can be read in. Of course, you will have to create one! Compile and run the code with small dimensions (n=10, m=10, l=10) and then try the big one as you did in the above exercise. When arrays are set as allocatable the compiler will not catch it, as with the Parameter statement, the problem will be noticed on run time or when the code is executed. When arrays are designated as allocatable they can be created and destroyed while the code is executing.
program main
implicit none
integer::n
integer::m
integer::l
integer :: i,j,k
integer :: io_dim

real(kind=dp),allocatable,dimension(:,:,:) :: x,y,z

! | create and input.dat directory in iof/ and type in a set of 3 integers one below the other

io_dim = 10

open(unit=io_dim, file="../iof/input.dat", status="unknown")

read(io_dim,*)n
read(io_dim,*)m
read(io_dim,*)l

allocate(x(1:n,1:m,1:l))
allocate(y(1:n,1:m,1:l))
allocate(z(1:n,1:m,1:l))

do k = 1,l
do j=1,m
do i=1,n
x(i,j,k)=float(i)*float(j)*float(k)
y(i,j,k)=float(i)*float(j)*float(k)
z(i,j,k)=float(i)*float(j)*float(k)

write(6,'(3f30.16,1x)')x(i,j,k), y(i,j,k),z(i,j,k)
enddo
enddo
enddo
deallocate(x)
deallocate(y)
deallocate(z)
end program main

PASSING ARRAYS THROUGH THE ARGUMENT LIST

Common mistakes occur when arrays and variables are passed or accessed through the argument list. The errors are due to address errors because the dummy arrays and variables were not assigned the correct address'. When compiling the codes one must use the -C flag to check where these types of errors occur and then correct them. In the example below Asub calls Bsub. The arrays are explicitly shaped in Asub and then addressed in Bsub as explicit dummy shaped arrays. The names of the arrays do not have to be the same what must be adhered is
  1. the leading and extent of the arrays (starting index of the array)
  2. the type of the arrays and variables (do not mix integer and real)
  3. Order in which they are addressed

Explicitly Shaped Array

When the bounds of the array is set by the parameter statement the extent of the array is fixed. If the bounds are exceeded and address error will occur

Explicitly Shaped dummy Array

When the bounds of the array are set by the calling program as shown in subroutine Bsub. The arrays in Bsub have their leading dimension  and extent set by the integers: ismax and jsmax.
  • The leading dimension is the starting index of the array
  • The extent of the array is the total size of the array

Automatic Arrays

When arrays are set as allocatable. The extent of the arrays are set at run time. The program can allocate and deallocate arrays while the program is running. However the allocation and deallocation step is an operation and therefore depending on the size of the arrays they can be cpu intensive. The approach to allocation/deallocation should not be reckless!

When arrays are allocated in a subroutine and they are local to the subroutine only then when the program exits the subroutine the arrays are destroyed automatically. If the same arrays are required in other routines then
  • they can only be addressed to routines called within the current subroutine. They cannot be addressed up the stack
  • should define them in the global.f90 module so that they can be accessed anywhere.

subroutine Asub
implictit none
integer,parameter :: n=3,m=3
real(kind=8),dimension(1:n,1:m) :: x,y,z
real(kind=8),dimension(1:n):: xx

x(1:,1:) = 2.0
y(1:,1:) = 3.0
z(1:,1:) = 4.0
xx(1:) = 5.0

call Bsub(n,m,x,y,z,xx)

end subroutine Asub
subroutine Bsub(ismax,jsmax,xi,yi,zi,xxi)
implictit none
integer,intent(in) :: ismax,jsmax
real(kind=8),dimension(1:ismax,1:jsmax) :: xi,yi,zi
real(kind=8),dimension(1:ismax):: xx

write(6,*) xi(1:,1:)
write(6,*) yi(1:,1:)
:
:
:
end subroutine Bsub


MODULES

In the past (f77) the most common way for procedures to have access to data types was through the common block. The common block could be confined to a file that a procedure would include to access the data types. Items included in the common block were commonly referred to as globals. The same method of using globals is used in C which include the global.h file in a procedure.
However all this changed for the better in f90. In f90 the common block was replaced by a powerful subset of the procedure family called Modules. The Modules could be compared to a Class in C++. Procedures like Subroutines and Functions can be included in a Module. This type of interface is called an explicit interface as shown in the next section. To use Modules as a repository of global elements that other procedures can access without having to write messy argument lists is simple and straight forward. When accessing or using modules the module source file should always be compiled before its dependencies. Suppose you have three files that access contents in global.f90, where global.f90 is a module file. To compile the program the global.f90 file is compiled 1st and then followed by the others.
To compile the above test case (be sure to have directory /lab5/global  with src/ bin/
  • ifc -w -g global.f90 main.f90 -o../bin/code.x

CONTAINS STATEMENT

An internal procedure is a procedure contained inside some host program or procedure. A main program may contain an internal function or subroutine. An external procedure may also contain one or many internal procedures. Internal procedures can only be invoked by their host programs. Anything declared in the host program is accessable by the internal programs: no need to use the argument list.

EXPLICIT INTERFACE

Create a directory called lab5/decomp/ and in it create the src/, bin/ and dat/ directories. Download the source files into the src/ directory only. You will be required to perform various tasks to further understand the concepts in programming. By now you should know how to compile, link and execute the program.

Explicit Interface

The official Linear Solver routine for this class is decomp.f90: this routines has been tested in Gams and contains two procedures (decomp and solve).  There is a driver.f90 program that calls decomp and solve. The decomp and solve procedures are in a Module creating an Explicit interface. You are not to modify or add anything into the routines! The contents of the code within each routine must be untouched. You are only to add the Module Interface as shown below.
THE REQUIRED ROUTINES
You will need to compile the decomp.f90 file 1st since it is now a Module and the only way the driver can access it is through a
  • Use statement
  • Call statement
Whenever there exists an explicit interface the module file is compiled prior to the calling programs

WHY SHOULD I USE AN EXPLICIT INTERFACE

When a procedure is an external procedure the compiler cannot catch errors regarding the elements in the argument list. If a Call statement to a Subroutine or function contains an item that is real(kind=8), but in the Subroutine it has been declared as an integer or real(kind=4) or even an array then the compiler will not catch this mis-match. The link step will also be successful and only when the code is executed will an address error show up. Now, if this same procedure is embedded in a module then the compiler will catch all these irregularities and only compile further until they are fixed!
In the files downloaded modify the number of items in the argument list in the driver.f90 file as shown below in column2 and then compile the files. Note your observations and the type of error message that is displayed.
Original and Correct Form
Incorrect Form to test the compiler
CALL DECOMP(NDIM,N,COND,IPVT,WORK,A)
CALL SOLVE (NDIM,N,B,IPVT,A)
CALL DECOMP(NDIM,N,COND,IPVT,WORK)
CALL SOLVE (NDIM,N,B,A)

 Assumed Shape Dummy Array vs Explicit Shape Dummy Array

Here is an example that shows two ways in which arrays are passed through the argument list. The safest way is to create explicit shape dummy arrays where the leading dimension and the extent of the dummy arrays is specified through the argument list. In fortran90 an assumed shape dummy array specification can also be used if the routine is in a module. When a routine is in a module an explicit interface is created between the calling program and the routine. With this interface the compiler is able to pass more detailed information regarding the called routine to the calling routine. The leading dimension, extent, type and etc of the array is known to the calling routine. Therefore the bounds do not need to be specified.
Module Linear_solver 
contains
SUBROUTINE DECOMP(NDIM,N,COND,IPVT,WORK,A)

IMPLICIT NONE
INTEGER :: NDIM,N

! | Assumed Shape dummy array:
! | If the routine is in a module creating an explicit interface then one can use
! | assumed shape dummy array specifications for the arrays in the argument list.
! | The extent and leading dimensions of the arrays in the argument list are defined
! | by the calling program.
! | Note this can only be used if the routine is in module like this one.

! REAL(KIND=8) :: WORK(:),A(:,:) ! assumed shape dummy arrays

! | Explicit shape dummy Arrays:
! | Commonly used method in passing arrays through argument lists. In this method the extent or size of
! | rows and columns of the arrays need to passed through the argument list. This method is commonly
! | used where as the above method is for more advanced users.

REAL(KIND=8) :: WORK(1:NDIM),A(1:NDIM,1:NDIM)
REAL(KIND=8) :: ANORM,T,EK,YNORM,ZNORM,COND

Debug the code

Introduction

Eventually everyone needs to use the debugger to trouble shoot their codes. Even programmers writing codes that run on super-computers use debuggers to fix and enhance performance of their codes. To complete a project 90% of the effort is exerted in debugging while the rest 10% depends on whether you paid attention in lab or not. The standard debugger on almost all unix type machines is a variation of the dbx debugger. The intel compiler version71 uses the dbx debugger but calls it idb. For version71 there is no gui support, but version 8.1 has gui support (code warriors use command line only!). The "idb" debugger is command line based and the more proficient the user gets with commands the faster the debugging can be accomplished. Knowing how to use a debugger is a major asset and the responsibility to learn it and use it should not be avoided. In this class you are expected to become proficient with the debugger.
All commands are typed at the (idb) prompt. When you first start the debugger, your program is ready to run, but has not yet started. To get a list of possible commands, type help

Dowload the Startup file

Customized commands can be placed in this file.

idb startup file for download: save this in your $HOME as .idbrc





Download the test Source Files

The set of source files listed below should be downloaded and saved in the src/ directory of lab_idb/. Do not change the names of the files. If you notice there is a global.f90 files included in this set, the global.f90 file is a module files unlike the other files.
main.f90
input.f90
solver.f90
output.f90
global.f90
input.dat

COMPILE AND LINK FOR DEBUGGING THE EXECUTABLE

When using a debugger the compile and link step need to include the debug flag: -g

<bash> ifc -c -w -g global.f90 main.f90 solver.f90 output.f90 input.f90

<bash> ifc -g global.o main.o solver.o output.o input.o -o ../bin/code.x

RUNNING THE code.x

The executable code.x will be located in ../bin directory. To run the executable the following command is used

NOTE: You should now be in the bin/ dir

32bit debugger (ifort or ifc71)


<bash> idb code.x

64bit debugger (ifort v90)

<bash> idb-e code.x

Gui version

<bash> idb -gui code.x or idb-e -gui code.x

IDB QUICK GUIDE

commands                                                                        What does it do
(idb) help										
run - begin execution of the program
print <variable name> - print the value of the expression
where - print currently active procedures
stop at <line> - suspend execution at the line
stop in <proc> - suspend execution when <proc or subroutine> is called
stop at <line> if(<logic>) - stop at certain line if a certain if condition is met
when at <line #> if (<logic>) {p <variable>} - print value of variable when at line and when logic is satisfied
cont - continue execution
step - single step one line
next - step to next line (skip over calls)
trace <line#> - trace execution of the line
trace <proc> - trace calls to the procedure
trace <var> - trace changes to the variable
trace <exp> at <line#> - print <exp> when <line> is reached
status - print trace/stop's in effect/break point info
delete <number> - remove trace or stop of given number or break point
call <proc> - call a procedure in program
whatis <name> - print the declaration of the name
list <line>, <line> - list source lines
registers - display register set
alias - list all the commands and their alias'
quit - exit idb




step1

Invoke the debugger using the command shown below

<bash> idb code.x

When the debugger loads the executable the following lines will show up on the shell

Linux Application Debugger for 32-bit applications, Version 7.2.2, Build 20030624
------------------
object file name: step1
Reading symbolic information ...done
idb:>
The -g option allowed the debugger to read all the information in the source code from which the debugging can be successful. If the -g option were not invoked during the compile and link step then no symbolic information would have been read.

step2: list line# line#

The first step after loading a executable is to list the contents of the main program from line 1 down to the next 50 lines.

weaponX:>l 1
weaponX:>l 1
      1         program main                            ! All programs have to have a main program header
      2
      3                 Use global
      4         implicit none                           ! All procedures have to have a implicit none command
      5         integer :: ismax,jsmax,ksmax
      6         integer :: io_write
      7         integer :: status
      8
      9
     10                 call input(ismax,jsmax,ksmax,io_write)
     11
     12 !       | Allocation step ::
     13
     14                         allocate(x(1:ismax,1:jsmax,1:ksmax),    stat=status)
     15                                 if(status /= 0) write(6,*) "deallocation failed at line 13"
     16                         allocate(y(1:ismax,1:jsmax,1:ksmax),    stat=status)
     17                                 if(status /= 0) write(6,*) "deallocation failed at line 16"
     18                         allocate(z(1:ismax,1:jsmax,1:ksmax),    stat=status)
     19                                 if(status /= 0) write(6,*) "deallocation failed at line 19"
     20                         allocate(w(1:ismax,1:jsmax,1:ksmax),    stat=status)
     21                                 if(status /= 0) write(6,*) "deallocation failed at line 21"
     22
     23                 call solver(ismax,jsmax,ksmax)
     24                 call output(ismax,jsmax,ksmax,io_write)
     25
     26 !       | Deallocation step ::
     27
     28                 deallocate(x,   stat=status)
     29                         if(status /= 0) write(6,*) "deallocation failed at line 14"
     30                 deallocate(y,   stat=status)
     31                         if(status /= 0) write(6,*) "deallocation failed at line 18"
     32                 deallocate(z,   stat=status)
     33                         if(status /= 0) write(6,*) "deallocation failed at line 20"
     34                 deallocate(w,   stat=status)
     35                         if(status /= 0) write(6,*) "deallocation failed at line 22"
     36
     37
     38
     39         end program main
weaponX:>

When you downloaded the .idbrc startup file one of the settings in the file allows the user to list a file 50 lines at a time.

step3: stop at line# or b line#

Now that we can see the main program its time to put some break points. A break point is like a stop sign which prevents the code from accomplishing its task any further.
Lets place the following break points
 idb:>b 10
[#1: stop at "main.f90":10 ]
weaponX:>b 20
[#2: stop at "main.f90":20 ]
Now lets check or list the break points we just inserted using the status option

idb:>status
#1 PC==0x8049a9f in subroutine main() "main.f90":10 { break }
#2 PC==0x8049f27 in subroutine main() "main.f90":20 { break }

From the status option we can list the our break points. If we want to delete the above breakpoints we can do so by

<idb>delete 1
<idb>delete 2

or

<idb>delete all

If you have deleted the break points then go back re-insert them please

 idb:>b 10
[#1: stop at "main.f90":10 ]
weaponX:>b 20
[#2: stop at "main.f90":20 ]

step4: run or r

The command "run" launches the debugger to run the code. The code will stop at the 1st breakpoint

[1] stopped at [subroutine main():10 0x8049a9f]
     10                 call input(ismax,jsmax,ksmax,io_write)


The screen by now is pretty cluttered so its a good idea to clear it and re-list the contents

weaponX:>sh clear
weaponX:> l 1

Whenever the programmer wishes to use a unix command the sh command precedes the unix command. The command that clears the shell screen in unix is "clear" and by preceding the command with "sh" the debugger screen was successfully cleared.

If the programmer wishes to list a part of the code from line# to line# the following list command would be used

 weaponX:> l 3 10


 weaponX:>l 1
      1         program main                            ! All programs have to have a main program header
      2
      3                 Use global
      4         implicit none                           ! All procedures have to have a implicit none command
      5         integer :: ismax,jsmax,ksmax
      6         integer :: io_write
      7         integer :: status
      8
      9
>    10                 call input(ismax,jsmax,ksmax,io_write)
     11
     12 !       | Allocation step ::
     13
     14                         allocate(x(1:ismax,1:jsmax,1:ksmax),    stat=status)
     15                                 if(status /= 0) write(6,*) "deallocation failed at line 13"
     16                         allocate(y(1:ismax,1:jsmax,1:ksmax),    stat=status)
     17                                 if(status /= 0) write(6,*) "deallocation failed at line 16"
     18                         allocate(z(1:ismax,1:jsmax,1:ksmax),    stat=status)
     19                                 if(status /= 0) write(6,*) "deallocation failed at line 19"
     20                         allocate(w(1:ismax,1:jsmax,1:ksmax),    stat=status)
     21                                 if(status /= 0) write(6,*) "deallocation failed at line 21"
     22
     23                 call solver(ismax,jsmax,ksmax)
     24                 call output(ismax,jsmax,ksmax,io_write)
     25
     26 !       | Deallocation step ::
     27
     28                 deallocate(x,   stat=status)
     29                         if(status /= 0) write(6,*) "deallocation failed at line 14"
     30                 deallocate(y,   stat=status)
     31                         if(status /= 0) write(6,*) "deallocation failed at line 18"
     32                 deallocate(z,   stat=status)
     33                         if(status /= 0) write(6,*) "deallocation failed at line 20"
     34                 deallocate(w,   stat=status)
     35                         if(status /= 0) write(6,*) "deallocation failed at line 22"
     36
     37
     38
     39         end program main


The debugger stopped at line 10 where the procedure input is called.
Sometimes listing a large portion of the code can be inconvenient, if the programmer only wants to list the current line the debugger is located at and a few lines above and below the following command would be used

 weaponX:> w

The lower case "w" will list 5 lines above and below the current line.

step5: step into or s

To step into the subroutine input we use the step into command which is aliased as  s

<idb>s
<idb>l 1

weaponX:>l 1
      1         Subroutine input(ismax,jsmax,ksmax,io_write)
      2                 use global                                              ! Module global that contains the type of
      3                                                                         ! x, y and z variables and arrays
      4         implicit none
      5
      6         integer :: io_read                                              ! open stetement assignment number: input
      7         integer :: io_write                                             ! open stetement assignment number: output
      8
      9         integer :: ismax
     10         integer :: jsmax
     11         integer :: ksmax
     12
>    13                 io_read = 101                                   ! assigning the unit number 101 to integer
     14                                                                         ! variable io_read
     15                 io_write= 102                                   ! assigning the unit number 102 to integer
     16                                                                         ! variable io_write
     17
     18                 open(unit=io_read, file="../bin/input.dat",status="Old")
     19
     20                 read(io_read,*) ismax                                   ! max counter in i
     21                 read(io_read,*) jsmax                                   ! max counter in j
     22                 read(io_read,*) ksmax                                   ! max counter in k
     23
     24                         read(io_read,*) xl                              ! x lower bound
     25                         read(io_read,*) xu                              ! x upper bound
     26
     27                                 read(io_read,*) yl                      ! y lower bound
     28                                 read(io_read,*) yu                      ! y upper bound
     29
     30                                         read(io_read,*) zl              ! z lower bound
     31                                         read(io_read,*) zu              ! z upper bound
     32
     33
     34         end subroutine input


step6: step, continue and next

step command

Continue pressing the "s" key until the debugger has reached line number 15 as shown above. Now print the value of io_read using the "print" command or letter "p".
Note: you can only print the value of an entity once the debugger has gone over it to the next line otherwise it will print garbage

<idb>p io_read

continue commad

Now jump to line 34 using a break point

<idb>b 34
<idb>c

The continue key "c" allows the debugger to execute everything between its current location and the breakpoint. Print the values of the input.dat

<idb>p ismax
<idb>p jsmax
:
:

To leave this routine you can either presser "s" to step off the last statement or you can use "return"

next command

The next command or "n" key is the same as the step command except it executes the procedure without going into it. If the debugger was on a CALL statement then the step command would allow the debugger to go into the subroutine for further debugging. When the next command is used the subroutine and its contents is executed immediately without having to go into the routine. Whenever the [opaque] message comes up use the next command and not the step command. You will have to re-run the code inside the debugger and avoid using the step command when the debugger is over a procedure CALL statement or some intrinsic function. If you have to go into the procedure then use "stop in [procedure name]" and follow it with a "c".

[special] continue command without breakpoint

Suppose line 34 in the above example was not a breakpoint, but the programmer desired the debugger to jump to that line from line 13. This can be accomplished using the "continue to line#"  command. In the example field below the continue command has been aliased to the letter "c"

<idb>c to 34
or
<idb>continue to 34

This command would take the debugger straight from line 13 to line 34 without having to use a breakpoint. Try this command later for practice.

step6: stop in [procedure name]

Besides using the step key, the programmer can jump straight into the desired routine using the "stop in [procedure name]" command

<idb> stop in output
<idb> c
or
<idb> bp output
<idb> c

The stop in command is followed by a continue key "c" or run command if the debugger has not started. The "stop in" command is aliased to "bp" as shown above. Once you are in the output subroutine lets do some checking and printing of arrays

<idb>b 30
<idb>c
<idb>sh clear
<idb>l 1

step7: print [name of variable or array]

Printing Arrays

Arrays can be printed in various forms
  1. whole array can printed
  2. one element of the array can be printed
  3. section of the array can be printed

<idb>p x
<idb>p y(2,3,4)
<idb>p w(1,2,:)

The print will be long so you will need to answer yes/no to get the idb prompt back. Also, when an array is printed the format is based on columns: the 1st column in the array is printed followed by the second and so on.

whatis command

Sometimes it is necessary to verify the type (real, integer, complex or character) of a variable or array. To ascertain the type of an entity the command "whatis"
is used on the entity in question

<idb>whatis x
<idb>whatis jsmax

Step8: quit

To quit the debugger the exit command or "q" key can be used

<idb>q

Step9: Redo

Now go back and start over and try to get comfortable with the debugger. You will be expected to use the debugger to trouble shoot the codes.

Advaced debugging

When debugging expressions inside loops that are nested it can get tedious and complicated. There is no point stepping through the i,j,k counters if you need to retreive a value of an array when i =2, j = 4, and k=7. Conditional statements (if blocks) can be used to stop the debugger at the specified counters to check the value of the array
  • In  some nested do loop we want to stop the debugger when
    • i=2
    • j=4
    • k=7

<idb>stop at "line number" if(i==2 .and. j==4 .and. k==7)
or

<idb>when at "line number" if(i==2 .and. j==4 .and. k==7) {p "variable" or "array"}

CAUTION: When using conditional statements in nested loops the debugger will take some time!

Recording input command for repeated use

Debugging involves correction of the source code. The user usually sees an error in the algorithm while debugging and then the user corrects the mistake in the source code. The new source code is now re-compiled and the new executable has to be reloaded into the debugger. When a new executable is reloaded into the debugger the preceding breaks and traps are removed and the status is an empty stack. To avoid having to re-apply the same traps and breaks the user can record the commands and replay them:

to record the input commands


<idb>record input {filename}

to execute the commands


<idb>playback {filename}

Creating an alias file

After a while commands can become tedious and repetitive and to optimize the debugging task a set of alias commands can be stored in the ".idbrc" file. The ".idbrc" file will be housed in your $HOME directory. This file is a startup file and so it should precede with a dot. Here is an example of what an .idbrc file may look like. The user of this file has customized his idb-e to do the following
  • attach a user defined name to the debugging experience
  • set the number of lines that will be listed
  • set the number of top/bottom lines to be listed
  • create a short cut to the unix clear command
    • all unix commands when accessed from idb should precede with the "sh" command
  • create an alias to the playback command for some input file
    • in this case the input file name is "file".

set $listwindow=53
set $prompt = "weaponX:>"
alias ss "s;w"
alias w " list $curline - 5:40"
alias pi "playback input"
alias cle " sh clear"