Previous Next Contents Index Doc Set Home


Pascal Programs

2


This chapter cites two examples that illustrate how to compile and execute a program. It also explains how to use the traceback facility to find out why a program fails. The sections are:

A Simple Pascal Program

page 7

An Interactive Pascal Program

page 10

Where Did My Program Fail?

page 13

Building a program with SPARCompiler Pascal requires three steps:

1. Writing a program in Pascal using an editor, and saving it in a file with a .p or .pas suffix

2. Compiling the <name>.p or <name>.pas file using the pc command

3. Executing the program by typing the name of the executable file at the system prompt


A Simple Pascal Program

The following is a simple Pascal program that converts temperatures from degrees Fahrenheit to degrees Celsius. Use an editor to type the code on your system and save it in a file called temp.p.

program temperature(output) ;

{ Program to convert temperatures from
 Fahrenheit to Celsius. }

const
	MIN = 32 ;
	MAX = 50 ;
	CONVERT = 5 / 9 ;

var
	fahren: integer ;
	celsius: real ;

begin
	writeln('Fahrenheit     Celsius') ;
	writeln('----------     -------') ;
	for fahren := MIN to MAX do begin
		celsius := CONVERT * (fahren - 32) ;
		writeln(fahren: 5, celsius: 18: 2) ;
 end ;
end.

Compiling the Program

Now compile the program with pc, the Pascal compiler, by typing at the system prompt:

hostname% pc temp.p
Pascal names the compiled version of the program a.out by default.

Running the Program

To run the program, enter a.out at the prompt. The output of temp.p is then displayed:

hostname% a.out
  Fahrenheit     Celsius
  ----------     -------
     32          0.00
     33          0.56
     34          1.11
     35          1.67
     36          2.22
     37          2.78
     38          3.33
     39          3.89
     40          4.44
     41          5.00
     42          5.56
     43          6.11
     44          6.67
     45          7.22
     46          7.78
     47          8.33
     48          8.89
     49          9.44
     50          10.00

Renaming the Executable File

It is inconvenient to have the result of every compilation in a file called a.out. If such a file already exists, it is overwritten. You can avoid this in either of the two following ways:

hostname% mv a.out temp

hostname% pc -o temp temp.p

Now run the program by typing the name of the executable file. The output follows:

hostname% temp 
Fahrenheit     Celsius
----------     -------
   32          0.00
   33          0.56
   34          1.11
    .           .
    .           .
    .           .


An Interactive Pascal Program

In Pascal, the predefined file variable, input, is equivalent to the operating system standard input, stdin. Similarly, the file variable, output, is equivalent to the standard output, stdout.

Following is a Pascal program that copies input to output. Use an editor to type the code on your system and store it in a file called copy.p:

program copy(input, output);

{ This program copies input to output. }

var
    c: char;

begin
    while not eof do begin
      while not eoln do begin
          read(c);
          write(c)
      end;
      readln;
      writeln
    end
end. { copy }

Compiling the Program

Use the pc command to compile the program and store it in the executable file copy. Here is the command format:

hostname% pc -o copy copy.p

Running the Program

Because the standard input and standard output default to the keyboard and the display screen, respectively, the program simply echoes on the screen each line you type on the keyboard. The program terminates when you type the end-of-file (Control-d) character at the beginning of a line. Try it:

hostname% copy<Return>
Hello, are you listening?<Return>
Hello, are you listening?
Goodbye, I must go now.<Return>
Goodbye, I must go now.
(Control-d)
hostname%

Redirecting I/O

To write the output to a file instead of to the display screen, use the redirection operator, >, followed by a file name. For instance, to write to a file called data, enter the following:

hostname% copy > data<Return>
Hello, are you listening?<Return>
Goodbye, I must go now.<Return>
(Control-d)
hostname%

Using the same program, but with the < operator to redirect input, you can print the file on the display screen:

hostname% copy < data<Return>
Hello, are you listening?
Goodbye, I must go now.

Using a File Name as a File Variable

You can redirect the program input or output to files by listing the files as file variables in the program statement. The Pascal library associates each (input, output) file variable with a file named in the program statement. For example, copy2.p lists data as the input file variable and output as the output file variable:

program copy2(data, output);

{ This program redirects input. }

var
    c: char;
    data: text;

begin
    reset(data);
      while not eof(data) do begin
      while not eoln(data) do begin
          read(data, c);
          write(c)
      end;
      readln(data);
      writeln
    end
end. { copy2 }

Assuming that the file data is still in the current directory, you can compile and run the program as follows:

hostname% pc -o copy2 copy2.p
hostname% copy2
Hello, are you listening?
Goodbye, I must go now.


Where Did My Program Fail?

SPARCompiler Pascal can trace why a program failed; its traceback utility finds the routine that triggers the error.

Using Pascal Traceback

Pascal traceback installs signal handlers on selected signals and dumps a backtrace when those signals are caught. The backtrace shows the chain of calls leading from the routine in which the error occurred, all the way back to the main program.

Pascal catches the following set of signals:

SIGQUIT

SIGIOT

SIGFPE

SIGSYS

SIGTERM

SIGILL

SIGABRT

SIGBUS

SIGPIPE

SIGLOST

SIGTRAP

SIGEMT

SIGSEGV

See the signal(3) man page for further information on these signals.

After the system produces the traceback, it continues with whatever action it would have taken if the interposer had not been in place, including calling a user signal handler that was previously set.

The traceback facility uses the debugger dbx. To obtain a traceback, SPARCworks must be installed on your system, and the directory containing dbx must be in your PATH environment variable. If the traceback routine cannot find dbx, it does not produce the traceback.

Use the -notrace command-line option to disable traceback.

Using a Sample Program with Segmentation Violation

A segmentation violation occurs when your program tries to reference memory outside your address space. The operating system detects this action and generates an error message. Following is an example program, SegViol.p, which contains a segmentation violation:

program SegmentationViolation;
type
  Pinteger = ^integer;

procedure ErrorInHere;
var
  IntVar:  integer;
  NullPtr: Pinteger;
begin
  NullPtr := nil;
  { Next statement causes a SEGV }
  IntVar := NullPtr^;
end;

procedure Call1;
  procedure Call2;
  begin
    ErrorInHere;
  end;
begin
  Call2;
end;

begin
  Call1;
end.

Compiling and Running the Program

When you compile and run the program, you receive output similar to the following. The first line indicates the name of the offending signal--in this case, a segmentation violation.

hostname% pc SegViol.p
hostname% a.out

*** a.out terminated by signal 11: segmentation violation
*** Traceback being written to a.out.trace
Abort (core dumped)

hostname% more a.out.trace

*** Stacktrace of a.out
*** Program terminated due to segmentation violation
  [3] __PC0__sigdie(0xb, 0xefffedf0, 0xefffec30, 0x0, 0x1, 0x0), at 0x12128
  ---- called from signal handler with signal 11 (SIGSEGV) ------
  [4] ErrorInHere(), at 0x115ec
  [5] Call2(0xefffefc8, 0xefffefa8, 0xefffef88, 0x0, 0xef74dd58, 0x0), at 0x11624
  [6] Call1(0x25400, 0x25800, 0x25b80, 0x25b80, 0x3, 0x0), at 0x11660
  [7] program(0x1, 0xeffff0fc, 0x4, 0xef7d0000, 0x2, 0xef74dae8), at 0x116a4
  [8] main(0x1, 0xeffff0fc, 0xeffff104, 0x25000, 0x0, 0x0), at 0x116e0
detaching from process 17266

In this example, ErrorInHere reported the error. The ErrorInHere procedure was called by Call1.Call2, which was in turn called by the main program. Routine names, such as Call1.Call2, indicate a nested routine. If Pascal cannot find the name of a routine, for example, because the executable file has been stripped, it prints the hex address.

Using the -g Option

If you compile the program with the -g option, the traceback also reports the arguments, the line number, and the file name of each routine.

Try compiling SegViol.p with -g:

hostname% pc -g SegViol.p
hostname% a.out

*** a.out terminated by signal 11: segmentation violation
*** Traceback being written to a.out.trace
Abort (core dumped)

hostname% more a.out.trace

*** Stacktrace of a.out
*** Program terminated due to segmentation violation
  [3] __PC0__sigdie(0xb, 0xefffedf0, 0xefffec30, 0x0, 0x1, 0x0), at 0x12128
  ---- called from signal handler with signal 11 (SIGSEGV) ------
  [4] ErrorInHere(), line 12 in "SegViol.p"
  [5] Call2(), line 18 in "SegViol.p"
  [6] Call1(), line 21 in "SegViol.p"
  [7] program(), line 25 in "SegViol.p"
detaching from process 17285

The program prints the ASCII values of character variables.

If you compile some modules with -g and others without, the line numbers may not be accurate for all the routines.


Previous Next Contents Index Doc Set Home