+ All Categories
Home > Documents > Systems Supplement for COP 3601 - University of North...

Systems Supplement for COP 3601 - University of North...

Date post: 23-Sep-2020
Category:
Upload: others
View: 0 times
Download: 0 times
Share this document with a friend
46
Systems Guide for COP 3601: Introduction to Systems Software Charles N. Winton Department of Computer and Information Sciences University of North Florida 2010
Transcript
Page 1: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Systems Guide for COP 3601: Introduction to Systems Software Charles N. Winton Department of Computer and Information Sciences University of North Florida 2010

Page 2: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 A Basic Guide for the Unix Operating System 1. 1 Using the Unix On-line Manual Pages Facility The following are some of the Unix commands for which you may display manual pages:

cal cat cd chmod cp cut date echo egrep ex fgrep file find gcc gdb grep kill less ln locate ls mail make man mesg mkdir mv nohup nl passwd pr ps pwd rm rmdir set sleep sort stty tail tee time touch tr tty uname umask unset vim wall wc which who whoami write

For example, to display the manual pages for the command "cp" enter

man cp Note that you may also enter

man man to find out more about the "man" command. In addition there may be commands unique to the local environment with manual pages; e.g.,

man turnin accesses a manual page for a project submission utility named Aturnin@ that has been added to the system. If you enter a command from the Unix prompt that requires an argument, the system will recognize that the command is incomplete and respond with an error message. For example, if the command "cp" had been entered at the Unix prompt the system would respond with the information such as shown below:

cp: missing file arguments Try `cp --help' for more information.

The "cp" command is a copy command. If the arguments which tell the command which file to copy and where to locate the copied file are missing, then the usage error message is generated.

Page 3: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 (Unix Guide) - Page 2 of 44 1. 2 The Unix System Text Editor The Unix text editor supports line oriented editing under the command "ex" and display editing under the command "vi" (here only "vi" is discussed, although it is ‘alias’ed to "vim" on most Linux systems; "vim" employs the same look and feel as "vi", but adds a number of additional features, such as keyword coloring options). The environment variable EXINIT is used to configure the editor each time it is invoked. Normally, users establish the value of EXINIT in the file ".profile" (or .bash_profile or .login), which contains commands executed automatically at log on. For example, a typical ".profile" might contain (among others) the 3 commands

EXINIT="set number showmode ignorecase tabstop=2" export EXINIT umask = 066

Command (1) establishes a value for variable "EXINIT" and command (2) "exports" it to the Aenvironment@. Whenever you execute "ex" or "vi" the Aenvironment@ is examined for "EXINIT" and its value is used to configure the editor, in the above case to show the line number of each edit line, display the edit mode status when not in command mode, ignore case distinctions when searching text, and tab in increments of 2. Command (3) establishes the file creation mode mask to provide you with all possible access permissions and deny read and write access to others (the UNIX command "chmod" is used to modify permissions - see below). These commands can also be executed at the UNIX prompt to change the initialization for "ex" or "vi" on the fly. They can also be changed during any editing session (using the :set command, see below). The text file .vimrc is used to configure "vim" whenever it is launched to take advantage of its various features (an example .vimrc file is in the appendix). If .vimrc is present, "EXINIT" is ignored when "vim" is launched. Given that "vi" is usually linked to "vim", launching "vi" most likely will actually launch "vim", so having a .vimrc file is a good idea . The editing features of "vi" are not supported by all terminal types. Starting the editor For line editing the editor is started by entering

ex <filename> and for display editing by entering

vi <filename> where <filename> (which is an optional entry) is the name of the file you wish to edit (or create, if it does not already exist). When you start under "ex", you can switch to "vi" by entering

<line-number> vi where <line-number> is an optional line number at which you want the initial display positioned.

Page 4: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 (Unix Guide) - Page 3 of 44 The command

Q (capitalized Q) switches your session to "ex" when you are in "vi". 1.3 The vi Editor "vi" has two modes of operation, command mode and input mode. Text is entered from input mode and most editing is done from command mode. Command mode When in "vi" command mode, the "ex" line editing commands can be entered by first entering a ":", then the rest of the command; for example,

:set

is a line editing command which displays all of the editor configuration values that are active for your editing session. To set a specific option, for example "showmode", enter

:set showmode

The command

:set noshowmode

turns the option off. The "showmode" option causes the editor to display mode information in the lower right portion of the screen whenever it is not in command mode. To display the status of all options that can be set enter the command

:set all

To repeat the last command line (e.g., to repeat a simple search and replace), enter

@: File positioning commands (Command Mode) Most of the file positioning commands can be preceded by an optional <count> value, which specifies how may times to do the operation (default is once). The following is only a partial listing of the available commands:

<Ctrl> f Forward full screen <Ctrl> b Backward full screen <Ctrl> d Scroll down half screen <Ctrl> u Scroll up half screen <Ctrl> e Scroll down one line <Ctrl> y Scroll up one line

+ Move cursor to 1st non-blank on next line - Move cursor to 1st non-blank on previous line $ Move cursor to end of current line H Home window line L Last window line M Middle window line B,b Back a word E,e Forward a word

Page 5: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 (Unix Guide) - Page 4 of 44

<number> G Line number to go to (omit line number to go to end of file)

/<re> Forward to next text matching regular expression ?<re> Back to prior text matching regular expression n Repeat most recent search, going forward N Repeat most recent search, going back

Delete commands (Command Mode)

dd Deletes a line (<cnt>dd deletes <cnt> lines) dw Deletes from cursor to end of word including trailing space de Same as dw, but leaves trailing space d$ Deletes rest of line x Deletes one letter

Put command (Command Mode)

p Inserts the most recent deletion after cursor or on next line (dd case) Leaving the vi editor (Command Mode)

:q Quit "vi" when file is unchanged ("ex" command) :q! Quit "vi", save no changes ("ex" command) :wq (see file I/O in section 1. 4 for more information on the "w" command)

or ZZ Write and quit, saving changes Other useful commands (Command Mode)

<Ctrl> L This command causes the screen to refresh itself from what is in the working buffer.

u Undoes changes made by the previous editing command U Undoes changes to current cursor line only J Joins the current line and the next Q To switch to the line editor "ex" . To repeat the last (non-ex) command % Locates the matching bracket (or parenthesis, or brace)

Input mode While in the command mode, entering any one of the following commands will cause an entry into the input mode.

a Append after the cursor i Insert before cursor A Append at end of line (same as "$a") o Open line below O Open line above r Allows replacement of a single letter

cw, ce, c$ Does dw or de or d$ and then goes into input mode R Allows replacement from cursor forward, unchanged text remains

Page 6: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 (Unix Guide) - Page 5 of 44 Returning to command mode Most commands are entered from command mode. The ESC key returns you to the command mode. 1. 4 The ex Editor While editing is normally done under the display mode provided by "vi", there are a number of useful block operation and other commands accessible only via the line editor "ex". The "set" command noted above is one of these. Keep in mind that any of these can be entered from "vi" by preceding them with ":". When actually in "ex", the colon is automatically supplied. A range of lines is specified by a pair of line numbers, for example

23,34

specifies lines 23 through 34. File I/O <line-no> r <file-name> Read the named file into the edit buffer after the

specified line (line 0 = at the beginning) <range> w <file-name> Write the specified range of lines to the named file, the

whole buffer, if no range is given Other block operations (the current line only, if no range is given) <range> d Delete specified range of lines <range> co <dest-line> Copy specified range of lines, placing after the destination line <range> m <dest-line> Move specified range of lines, placing after the destination

line <range> > Move the specified lines the value of Ashiftwidth@ to

the right (installs spaces, not tabs) <range> < Move the specified lines the value of Ashiftwidth@ to

the left (installs spaces, not tabs) Search and replace <range> s/<pattern>/<replacement>/gc (see note below RE separator character “/”)

options: g = all occurrences c = confirm before replace

Over the specified range, the first occurrence of the pattern in each line is replaced if no options are specified. Note: a control character may be entered in a <pattern> or <replacement> string by first entering a preceding <Ctrl V>. Also, for current versions of ex the first character following s determines the separator. “/” is typically used unless it appears in the <pattern> or <replacement> string.

Page 7: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 (Unix Guide) - Page 6 of 44 Other useful commands

f Current file name information

<line-no> vi Shift to "vi" at the line

sh Temporarily leave editor (to do other Unix commands, including starting another "vi" session); return by "exit"

!<cmd> Execute <cmd> in shell, then return (e.g., :!ls )

1. 5 Listing a File on Your Terminal Once you have created a file, Unix provides several means of listing it to standard output (usually your terminal).

cat <filename> displays the file in raw form.

nl <filename> displays the file with line numbers.

less <filename> displays the file one screenfull at a time allowing forward and back movement. “less” is configured by the environment variable “LESS”, the value of which can be obtained by entering

echo $LESS

which typically will return something like

NCeMPM?f%f\: in page %d of %D (line %l of %L):piped input - in page %d (line %l).

The effect of the configuration parameters given by “LESS” can be determined from the “man” page for “less”, but in a nutshell for the above case are

N=line nbrs, C=clear screen , e=quit at EOF , M=use long prompt, PM=long prompt message as follows (with %f replaced by file name, %d replaced by page number, %l by line number).

If desired, the value of LESS can be reset in your login script (e.g., .bash_profile). The name “less” is a takeoff on the name of the older Unix command named “more” which could move ahead in the file display (to show more), but not back. For example, at a screen pause, entering

3g will position the display with line 3 at the top at the top of the screen and entering g will position line 1 at the top. Normally, the “PgUp” and “PgDn” keys on your keyboard will also function to advance to the next or the previous screenful. Entering

q will terminate the display.

Page 8: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 (Unix Guide) - Page 7 of 44 1. 6 Other Commonly Used Unix Commands Directories

Unix employs a Atree-structured@ directory system; e.g.,

root

usr lib

bin include

The Apath@ to the directory "bin" is "/usr/bin" (root is given by "/" alone). The file "xfile" in this directory is accessed as "/usr/bin/xfile".

pwd Displays the path to the current directory usage: "pwd"

ls Displays the contents of a directory

usage: "ls" (no options = list names in current directory) "ls -l" (-l = long listing, including permissions) "ls -q" (-q = show nonprintables in names as "?") "ls -R" (-R = recursively list subdirectories) "ls -a" (-a = also show . prefaced names) "ls -t" (-t = sort by time modified) "ls -F" (-F = as appropriate append classifier [*/=@ or|])

Examples: ls (list file names: current directory)

ls -l (list names, but in long format) ls –t –F (or –tF) (list names sorted by time, with classifiers) ls –la (long form, including those prefaced with .) ls /usr/bin (list file names: /usr/bin directory)

ls -l /usr/bin (list names, but in long format)

cd Changes the current directory usage: "cd <path>" (<path> = location of directory)

"cd" (changes path to HOME directory)

Example: cd /usr/include

mkdir Makes a directory under the current directory

usage: "mkdir <dirname>"

Example: mkdir project (the directory "project" is a subdirectory of the

current one - see "pwd" above)

rmdir Deletes a directory, but only if it is empty usage: "rmdir <dirname>"

Note: adding –-color "always" to the command line options for ls will cause the color patterns given by the shell variable LS_COLORS to be used by the ls display.

Page 9: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 (Unix Guide) - Page 8 of 44 Files

cat Displays the contents of a file usage: "cat <filename>"

od Displays the contents of the file byte by byte (octal dump)

usage: "od -xc <filename>" (exhibits the file byte by byte in both hex and ASCII)

grep Search a file for a pattern

usage: "grep <pattern> <filenames>" "grep -n <pattern> <filenames>" (-n = show line numbers) "grep -r <pattern> <directory>" (-r = search subdirectories recursively)

Example: grep -n 'symbtab' pass1.c externs.c pass2.c

cp Copies one file to another (creating a duplicate of the file, in contrast to ln, which

creates a 2nd link to an existing file or directory - see below) usage: "cp <source-name> <target-name>"

Example: cp /usr/local/lib/sic/loader temp (copies "loader" from another directory to the current one, but as the file named "temp")

rm Removes a file (unless there is more than one link to it; see ln below)

usage: "rm <filename>" (deletes the named file) "rm -r <dirname>" (delete directory, files and all) "rm -i *" (-i = user is interactively prompted

whether to delete each file (y or n); * = all files in current directory)

mv Renames a file usage: "mv <oldname> <newname>"

ln Make a link to an existing file or directory

(Each directory entry is a Alink@ to a file or directory, so the ln command is simply a means for creating an alternate link to a given file or directory. Note: rm only deletes a file if the link is the only one and the user has the necessary write permission for the directory containing it).

usage: "ln <filename> <linkname>" "ln -s <directoryname> <linkname>"

Examples: ln /usr/local/lib/sic/loader loader

(links the file "/usr/local/lib/sic/loader" in the "/usr/local/lib/sic" directory to "loader" in the user's directory)

ln –s /usr/bin/ utils

(links the directory "/usr/bin/" to "utils" in the user's directory)

Page 10: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 (Unix Guide) - Page 9 of 44 File access

chmod Changes the file mode (which governs file access permission) usage: "chmod <mode> <filename>"

mode is a 3-digit number <d1><d2><d3> where <d1> = the file access the owner allows him/herself <d2> = the file access granted the owners account group <d3> = the file access granted to everyone else. Each digit is determined by adding a combination of

4 = read permission 2 = write permission (also gives delete permission) 1 = execute permission

Examples: chmod 750 myfile

(grants all permissions to the owner, read and execute to the group, and none to others) Note: the command "ls -l myfile" will show the current

permissions for the file "myfile".

chmod 744 . ( . = current directory)

User information

who Shows who is logged on usage: "who" (who is logged on)

"who -u -H" (same as who plus header and idle time)

write Send message to another user usage: "write <user>" (enter message; end with <Ctrl>d )

mesg Permit or deny messages from other users

usage: "mesg y" "mesg n"

mail Send or read mail

usage: "mail <user>" (send mail to a user; enter message, a single "." on a line ends the message)

"mail" (read mail; for each message a "?" prompt gives the option to delete (d), print again (p), or go on (<CR>)

date Displays the time and date

usage: "date"

cal Displays calendar information usage: "cal -y" (calendar for current year) "cal -3" (calendar for previous, current, and next month) "cal" (calendar for current month)

Page 11: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 (Unix Guide) - Page 10 of 44 User characteristics

passwd Change login password usage: "passwd" (prompts will insure it is done OK)

Miscellaneous

echo Echo arguments to standard output usage: "echo <argument>"

(This command is useful for producing diagnostics in command scripts (see below), sending known data into a pipe, and for examining system variables; e.g., "echo $HOME")

1.7 Other Unix Features Pipes Unix commands normally receive input from a standard input stream called "stdin" and send output to a standard output stream called "stdout". Unless told otherwise, Unix uses the terminal as the standard I/O device. A pipeline is a sequence of one or more commands separated by the character "|" to modify the assumptions regarding standard I/O. When a pipeline separates two commands, the standard output of the first becomes the standard input to the second. This avoids the need to generate intermediate files to accomplish the same purpose. For example,

cat cmdfile | myproc pipes the standard output from "cat" (which would otherwise go to the terminal) as the standard input to some procedure ("myproc") which would otherwise be expecting input from the terminal. Directing standard input/output from/to files The pipeline example above simply piped a file listing to be the standard input to some procedure. In this particular case, it could just as well have been accomplished by redirecting standard input:

myproc < cmdfile (use the file "cmdfile" as standard input). Likewise, standard output can be sent to a file by redirecting it:

myprog > listfile (direct output from "myprog" to "listfile") or myprog >> listfile (append output from "myprog" to "listfile").

Both input to a procedure and output from the procedure can be directed; e.g., myproc < cmdfile > listfile

Page 12: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 (Unix Guide) - Page 11 of 44 Standard error Error reports generated by executing a Unix command are sent to a separate standard output stream called "stderr". Standard error output is unbuffered and so is sent immediately to the terminal unless redirected. The following would redirect standard output as before and redirect standard error to another file:

myprog > listfile 2>errfile The notation 2>&1 puts standard error on the same stream as standard output so

myprog > listfile 2>&1

redirects both standard output and standard error to the same file. 2 is the file descriptor for stderr, 1 for stdout (and 0 for stdin). Note that no spaces are allowed between 2, >, and the filename. Unix command scripts A series of Unix commands stored in a file may be executed via the dot command or the sh command (which is linked to bash on most Linux systems); e.g.,

. cmdfile sh cmdfile

This is the simplest form of what is called a command script. Usually the first line of the file is used to identify the shell to be used; e.g., #!/bin/bash specifies the “Bourne again” shell, the default Unix shell for Linux. You might need to enter which bash to determine the directory where the “bash” shell is located. If the file is marked as executable (using "chmod") and “.” is appended to your “PATH” environment variable (i.e., your local directory is in the command search path - see Section 2.1 below), then the script may be executed simply by entering its name (and the bash shell will be used to run the script, even if executing from within another shell). A command script may also be designed to have operands. These are referenced inside the script as "$1", "$2", ... A particular Unix Ashell@ (the command interpreter) may provide varying ways (e.g., Aif@ statements, Awhile@ groups, etc.) of processing a command script. As an example, construct a file named “list” containing

if [ $1 = "d" ]; then ls -lA | egrep '^d|^l' else ls -l | egrep -v '^d|^l' fi

and "chmod" the permissions to make it executable. Then when “list d” is executed only information on directories (and links) is listed and when “list” is executed information on everything other than these is listed.

Page 13: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 1 (Unix Guide) - Page 12 of 44 Explanation: For information on writing shell scripts with control structures consult a standard reference such as A Practical Guide to Linux by Sobell. It is worth noting that the spacing around the brackets in this example is required and that the command lines to be executed cannot reside on the same line as any of the “if-else” controls. For this script, in either case the output of “ls -l” is piped to “egrep”, but in the first case the lines from “ls” beginning with “d” or “l” (given by the regular expression “^d|^l”) are selected and in the second (the “-v” option) anything but these are selected by “egrep”. Note that “ls” has no means of doing such a separation by itself. Background tasks A Unix command followed by "&" will be run in the background, with foreground control immediately returned to the user for continuing work. For example,

cc myprog.c myclib clib.3601 & will start compile and link-edit of "myprog.c" in the background and return control of the terminal to the user. The user may then do some other work, such as editing a file. If the compilation running in the background generates any messages, they will be lost. To capture any messages produced, one strategy is to redirect standard output to some file; for example,

cc myprog.c myclib clib.3601 > msgfile & A better strategy is to use the Unix "nohup" command. This command runs the command to completion, even if the user logs off. Moreover, standard output is directed automatically to the file "nohup.out". The command sequence for the above example would now appear as

nohup cc myprog.c myclib clib.3601 & When a background task is run, the system's only response is a process id. The process id's of all tasks allocated to the user can be determined by entering a "ps" command, simply

ps To terminate a background task, use the Unix "kill" command; for example, if the process id is "6123", then

kill 6123 will terminate the process. Use this command with caution! The process may trap the kill signal and not terminate (ie., it is in the middle of a file write and can’t terminate without damaging the file). In this case,

kill -9 <process-id> will terminate the process, but it is user-beware for obvious reasons (you must be desperate to use this!).

Page 14: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 Using C in a Unix Environment

In this chapter, the requirements for dealing with C programs under Unix are described. The reader is assumed to have a working knowledge of the C language and its syntax. A number of C language techniques and library functions useful in writing system programs such as assemblers, loaders, and macro processors are described. Many of these techniques as presented in standard C reference materials are treated in a generalized fashion which may obscure their potential use for a particular purpose.

2.1 Unix cc Command (or gcc)

The "cc" command is designed to provide a number of services for handling C programs. A free (ANSI) version of C that can be installed in most Unix environments is available from the GNU Project of the Free Software Foundation and is the native compiler for Linux, where "cc" is implemented by linking it to "gcc". At the level of this discussion, "cc" and "gcc" may be used interchangeably; hence, only "cc" is referenced throughout.

Compile and link-edit

The simplest use of "cc" is to compile and link-edit C source files. By definition, a C source file name must be qualified by ".c", otherwise "cc" will assume it is simply a file to be passed on to link-edit. Unless otherwise specified, the load module produced is stored in the file named "a.out". For example,

cc myprog.c

compiles and link-edits the C source file "myprog.c" (constructed via one of the Unix text editors) placing the resulting load module in "a.out" if the process is error free. Assuming the program is not using parameters (command line parameters are discussed in Section 2.3) and “.” has been appended to your “PATH” variable (PATH=$PATH:.), it can then be executed by entering

a.out [otherwise you would need to enter ./a.out ] "cc" can handle multiple source files; for example, the command

cc globals.c mainprog.c sub1.c sub2.c

compiles four C source files (including one which perhaps consists simply of global variables) and link-edits them, the resulting load module going in "a.out". The "-o" option is used to specify the name for the load module; for example,

cc myprog.c -o myprog

will generate the load module under the name "myprog". If the program does not require parameters (and “.” has been appended to your PATH variable), it may then be executed by entering

myprog

(passing parameters to programs when invoking them is discussed in Section 2.3 below).

Page 15: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 14 of 44 Compile without link-edit If the "-c" option is specified, "cc" simply suppresses the link-edit step and does not destroy the object files. For example, the command

cc -c globals.c mainprog.c

compiles "globals.c" and "mainprog.c", leaving the object files from the compilation in the user's directory under the names "globals.o" and "mainprog.o". Chapter 3 discusses how such files can be collected in object module libraries for subsequent use. The command

cc globals.o mainprog.o sub1.c sub2.c

will result in the compilation of "sub1.c" and "sub2.c" with the resulting object modules along with the pre-existing object files "globals.o" and "mainprog.o" being passed to link-edit. In general, "cc" passes files not qualified with ".c" on to link-edit without examining them. In particular, if "mylib" is a library of object modules (see Chapter 3), the command

cc myprog.c mylib

will pass this library to link-edit where it will be searched for any unresolved symbolic references. When invoked by "cc", link-edit implicitly searches the standard C library seeking to resolve any symbolic references remaining after all other object modules and libraries specified to "cc" have been processed. In particular, for the above example, if "mylib" has a version of "printf" in it, then it will be used instead of the one in the standard C library since "mylib" is processed first, resolving references to "printf". Normal cc format for COP 3601 C subroutines for echoing standard I/O under program control are supplied to students in COP 3601 in the object file "hlib". These include "hputs", "hgets", "hprintf", and "hscanf" (described in Section 2.4). These routines behave exactly like their standard counterparts, and additionally produce a log file (named "hlib.log") for selective documentation of interactive program behavior. Linking these routines into a user program simply requires putting "hlib" in the user space and adding it to the "cc" command; for example,

cc myprog.c hlib Other cc options The "-g" option causes the C compiler to generate additional information which the symbolic debug programs such as "gdb" can employ. How to use "gdb" is the topic of Chapter 4. The "-O" option (capital "O") directs the C compiler to perform an optimization phase. This option is ordinarily not used for programs under development.

Page 16: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 15 of 44 2.2 Debugging C Programs The C compiler does not produce diagnostic information such as a cross-reference listing or a source listing with flagged compile time errors. If there are compile time errors, the compiler sends an error message to standard error (normally, the video display) noting the (approximate) line number on which the error occurred and the nature of the error. If there are too many errors, the compilation aborts. Sometimes a simple error (such as a minor syntax error) will propagate many subsequent errors. For example, if a variable declaration has a syntax error, the variable will probably be flagged as undefined everywhere it is referenced in the program. Normally, compile time errors can be corrected by close examination of the source code in the vicinity of the error as to the problem reported. Using the Unix nl command (see Section 1.5) and redirecting standard error from the cc command (see Section 1.7) will produce a suitable listing file for debug purposes; e.g.,

nl myprog.c > listfile cc myprog.c clib.3601 2>>listfile

constructs a listing file of the program with line numbers using nl and then appends any error report from cc. You may wish to experiment with shell scripts to build a suitable single command for this procedure. Acore dumped@ Execution time errors usually result in a Acore dumped@ message. A very common error which inevitably causes a Acore dumped@ message is a bad "scanf" parameter; namely, a variable's name rather than its address is supplied for the parameter. Always check variable names used in a "scanf" to see if the address indicator "&" is needed (it generally is, the major exception being array and pointer variables). If the program is compiled with the "-g" option, then starting the source program debugger gdb by executing

gdb a.out core<seq #>

after receiving the Acore dumped@ message will usually pin-point the source of the problem. "gdb" is covered more thoroughly in Chapter 4. Stay away from scanf for interactive input "scanf" is designed for use with machine generated text. For interactive input, it is recommended that you use "fgets". If the formatting features of "scanf" are needed, it is easy to combine "fgets" with "sscanf" to achieve the desired formatting. As a warning to the wise, the code

printf("Do you wish to continue (y/n): "); fgets(answer,3,stdin); [ #include <stdio.h> defines stdin ] sscanf(answer, "%c", &a); [ fgets reads 1 character fewer than specified]

[string variable “answer” captures user’s <Enter>] appears to be equivalent to

printf("Do you wish to continue (y/n): "); scanf("%c", &a);

Page 17: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 16 of 44 In the second case, however, the user input from the keyboard, including the user’s <Enter>, goes into the (standard input) I/O buffer. The first character in the buffer is picked off and placed in the variable "a", but the <Enter> remains in the I/O buffer in wait for the next call to "scanf". If

printf("Do you wish to continue (y/n): "); scanf("%c", &a);

is executed again, "scanf" does not wait for the user to enter a response since the input buffer still has something in it (the <Enter> from the previous user input). Consequently, the program does not behave as intended. Using "sscanf" eliminates the problem since a string serves in place of the I/O buffer and can be explicitly under program control. Don't nest comments The attempted comment line

/* this is /* not */ what it at first appears to be */ will cause an error since the second "/*" is assumed to be part of the comment. The C compiler will then attempt to decipher as code the text "what it at first ..." and so generate an error. Using "=" where "==" was intended (or "&" or "|" instead of "&&" or "||") This is a particularly common error for those who code in languages in addition to C. The phrase

if (x = 5) has a semantic interpretation; namely, Aassign the value 5 to x and use this value for the condition test@. Since 5 is non-zero the condition is Atrue@. If what the programmer intended was

if (x == 5) note how dramatically program behavior could be affected. Unintended null statement An inadvertent semi-colon may generate an unintended null statement, particularly with constructions such as "if", "for", or "while". For example, in the following statement an unintended semi-colon makes the object of the "if" clause null:

if ( x >= 1 ); printf("\nx has value %d", x);

The "printf" statement is then executed regardless of the value of x.

Page 18: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 17 of 44 Unintentional overwrite of other code When using pointers, or functions such as "strcpy", it is easy to unintentionally overwrite areas of object code resulting in mysterious program failure; for example,

/* char c; */ strcpy(&c, "yes");

will copy 'y','e','s','\0' into memory beginning at the address of "c" and thus clobbering three bytes of storage beyond the address of "c". Use the DEBUG feature obtained from the include file "cop3601.h" The single most effective technique for isolating errors in the program logic is judicious use of "printf" statements. The DEBUG feature in the include file "cop3601.h" provides a simple means of installing "printf" statements that can be easily enabled or disabled. DEBUG is turned on by starting the program with

#define TESTING #define is a C preprocessor command (see Section 2.5). When #define TESTING is included in the program code, DEBUG is enabled by the preprocessor. Then the "printf" statement given by the following DEBUG statement

DEBUG( printf("This is a DEBUG printf"); ) will be executed. If "TESTING" is not defined, "DEBUG" is disabled and the "printf" statement is not executed. In general, when "TESTING" is defined, whatever command is inside the parentheses of a "DEBUG" statement will be executed. If simultaneous output to the screen and the "hlib.log" file is desired, "hprintf" can be used instead of "printf". The general layout of the code to turn on the DEBUG feature is

#define TESTING #include "cop3601.h"

. . . main()

{ . . . } Removing the "#define TESTING" statement turns off the DEBUG feature. Note that the DEBUG statements can thus be left in place. It is recommended that DEBUG statements be constructed with some thought; for example,

DEBUG( printf("\nIn main in 1st loop x=%d, i=%d", x, i); ) provides locator information and identifies the variables being probed together with corresponding values.

Page 19: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 18 of 44 2.3 Useful C Characteristics A few native C characteristics particularly useful to students in COP 3601 are described in this section. Converting text to ASCII If a character value is assigned to an integer variable, it is converted to binary as an integer with leading 0's and its ASCII code in the rightmost byte. This Apure binary@ form can then be converted to text using "sprintf" to generate the hex representation of the ASCII code ("sprintf" is discussed further in Section 2.4); for example,

/* int ic; char s[81]; */ ic = 'a'; sprintf(s, "%X", ic);

places the text "61" (the ASCII representation of 'a' in hex) in the string "s". In fact, the abbreviated form

sprintf(s, "%X", 'a'); has the same effect. By using this tactic in a loop, a text string can be easily converted to show its ASCII representation in hex; for example,

/* int i, j; char s[161], t[81]; */ for (i=0, j=0; i < strlen(s); i++, j+=2)

{ sprintf(&t[j], "%X", s[i]);

} places in the string "t" the ASCII representation in hex of the characters in the string "s". This is exactly what is needed to resolve an assembly language storage instruction such as

C2EX BYTE C'This is a message' into object code; i.e., the ASCII form of the text "This is a message" can be generated using the above strategy.

Page 20: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 19 of 44 Setting a string to empty An empty string is one for which the first position is the string terminator character ('\0'). Consequently, the statement

/* char s[81]; */ s[0]='\0';

is equivalent to

strcpy(s, ""); but the first is far more efficient. Predefining fixed tables using external variables A large table such as a table of op codes and corresponding values can be easily isolated in a separate module holding external (global) variables (see also Section 3.6). For example,

struct opitem {

char optext[10]; int opval; int oplen; char opxe;

}; struct opitem Optable[] =

{ "ADD", 0X18, 3, 'S', "ADDF", 0X58, 3, 'U',

. . . "SHIFTR", 0XA8, 2, 'X',

. . . "WD", 0XDC, 3, 'S'

}; int Tsize = sizeof(Optable)/sizeof(struct opitem);

This might comprise the externally defined op code table used by a SIC assembler. The global variable "Tsize" automatically provides a count of the number of op codes in the table, even if more are added later! Remark: note the convention of capitalizing the first letter of an external variable to more readily identify it as such in program code.

Page 21: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 20 of 44 A program module needing to use "Optable" would include the type definition for "opitem" and an external specification for "Optable" and "Tsize"; for example,

struct opitem {

char optext[10]; char opval[3]; int oplen; char opxe;

}; extern struct opitem Optable[]; extern int Tsize;

The module containing the external variables can be stored in a personal library set up by the user (see Chapter 3) or carried locally in a ".o" file; for example, if the external variables are in the file "ex.c", then the "cc" format

cc -c ex.c will compile the module into the module "ex.o". For any code needing the external variables, the "cc" format

cc myprog.c ex.o will pull the module with the needed external variables in behind the compilation of the program. The items in "Optable" can be exhibited by code such as

/* int i */ for (i=0; i < Tsize; i++)

{ printf("%9s %2s %d %c", Optable[i].optext,

Optable[i].opval, Optable[i].oplen, Optable[i].opxe);

} Passing command line arguments to "main" Suppose you wish to execute a program for assembling code in the file "prog.sic" by using a Unix command line as follows:

assemble prog.sic In general, when a program is invoked, Unix implicitly provides the "main" module with two arguments via which command line arguments can be determined (they are ignored unless the programmer establishes code to utilize them). The first argument is a count (at least 1) of the number of tokens on the command line and the second is an array of string pointers, one for each token. Each of these pointers addresses a string of characters which comprise the token. For example, suppose the main module is

Page 22: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 21 of 44

#include <string.h> main(argc, argv)

int argc; char *argv[];

{ char sourcefl[15]; if (argc < 2)

{ askuser(sourcefl);

} else

{ strcpy(sourcefl, argv[1]);

} sicassemble(sourcefl);

}

stored in the Unix file "myassembler.c" and compiled by

cc myassembler.c askuser.o sicassemble.o -o assemble Recall that the option "-o assemble" names the execute module "assemble" instead of "a.out". Then the command

assemble prog.sic

will generate "argc" with value 2 and "argv[0]" pointing to the string "assemble" (the 1st token) and "argv[1]" pointing to the string "prog.sic" (the 2nd token). In this case the "else" portion of the above code will be executed. If the user simply enters

assemble

then "argc" has value 1 and the routine "askuser" in the "if" portion of the code is executed, presumably to interactively obtain the name of the source file from the user. 2.4 Useful C functions Among the very large number of predefined C functions that are available, a small number particularly useful to students in COP 3601 are described in this section. Functions in the executable "hlib" as well as ones from the standard C library are discussed. Since most of these functions are associated with one of the include files "stdio.h", "string.h", "ctype.h", and "cop3601.h", most C programs for COP 3601 should begin with

#include <stdio.h> #include <string.h> #include <ctype.h> #include "cop3601.h"

The functions prefaced by "h" (e.g., "hprintf") append a copy of what they generate on the screen to the file "hlib.log". The "hlib.log" file must be manually removed by

rm hlib.log

to begin a fresh log.

Page 23: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 22 of 44 puts, fputs, hputs The simplest way to output a string is with "puts"; for example,

puts("\nThis is an example");

sends the string (on a new line) to standard output (normally the display). "hputs" is the same, except that in addition to sending the string to standard output, the string is appended to the file "hlib.log" in the user's file space. "fputs" is used to output a string to a file. In this case, a file designator (for a file open for output) must be additionally given; for example,

/* FILE *fnum */ fputs("This goes on the current line of the file\n", fnum);

sends the string to the file designated by "fnum" ("fnum" is established when the file is opened (discussed below)). gets, fgets, hgets The simplest way to input data is with "gets"; for example,

/* char strng[81]; */ gets(strng);

inputs from standard input into the string "strng" until a new line character ('\n') is received (from a terminal, a carriage return generates a new line character). "hgets" behaves the same as "gets", except that the string obtained from standard input is also appended to the file "hlib.log" in the user's file space. "fgets" is simply a variation analogous to "fputs", where the input is taken from a file; for example,

/* FILE *fnum; strng char[133]; */ fgets(strng, 133, fnum);

inputs from the designated file (opened for input (discussed below)) into the string "strng" until either 132 characters or a new line character is received. Note that in contrast to "gets", "fgets" limits the amount of data retrieved, and consequently is preferred for user interaction (in which case the file pointer used is "stdin" as defined by "<stdio.h>"). This is not an issue with "hgets", which limits the "get" to 255 characters. printf, fprintf, sprintf, hprintf Using "printf" in conjunction with the "DEBUG" facility was discussed in Section 2.2. This function and its variations provide the principle means of generating formatted text. They all use the same formatting technique. The only difference among these functions is where the formatted text is sent. The differences are summarized as follows:

printf: formatted text sent to standard output (usually the display) fprintf : formatted text sent to a designated file sprintf: formatted text sent to a designated string variable hprintf: formatted text sent to standard output and simultaneously

appended to the user file "hlib.log".

Page 24: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 23 of 44 "sprintf" was employed in Section 2.3 with the format phrase "%X", which means format the corresponding argument as an integer in hex using capital letters for the hex digits A,B,C,D,E,F. The most commonly used format specifiers for COP 3601 are

d - format as an integer in decimal x - format as an integer in hex X - like "x" except use capital letters for the hex digits A,B,C,D,E,F s - format as a character string c - format as a single character

The minimum field width is specified by a leading integer; for example,

/* int ic */ printf("%10X", ic);

specifies the formatted form of variable "ic" is to be placed in a field of width at least 10 (if more than 10 is required, the field is given additional space). Unless otherwise specified, the formatted text is right-justified in the field. To left-justify, a "-" modifier is used; for example, printf("%-10X", ic);

places the formatted text beginning on the left side of the field. Since numbers are normally right-justified in report formatting, the "-" modifier is normally not used with the format specifiers "d", "x", and "X". Since strings are normally left-justified, a "-" modifier is almost always used with the format specifier "s". For right-justified text, the field is padded on the left with blanks. If the length specification is given with a leading 0, then padding is done with 0's instead (even for strings!). This is a very useful fact when writing an assembler; for example, the assembler directive

START 100

specifies a (hex) starting address of 100 which must be converted to "000100" in the object code file. If the variable "operand" represents the string constant " 100", then the sequence

/* char operand[20]; FILE fnum */ fprintf(fnum, "\n%06X", strtol(operand, NULL, 16) );

first converts the base 16 (hex) string " 100" to an integer using "strtol" and then converts it back to a string in the desired form, sending the result as a new line in the file identified by "fnum". "strtol" is discussed further below. To fix the field size, both a minimum and a maximum field size should be specified; for example, printf("%-15.15s", strng);

designates that the string variable "strng" is to be formatted (left-justified) into a field of width at least 15 and at most 15 (given by the ".15" qualifier).

Page 25: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 24 of 44 printf example An assembler report format might require the following appearance: loc code source statement 0000 EXAMPLE START 12C 0000 17202D TOP STL RETADDR 0003 4B101036 +JSUB SETUP . . . 002A 5448495320 MESSAGE BYTE C'THIS IS A MESSAGE' 004C F1 DEV BYTE X'F1' . . . The "printf" statement

printf(" %-7s%-12s%-s", "loc", "code", "source statement"); establishes the header, whereas

/* int lcntr; char objline[121]; char sourceline[81]; */ printf(" %04X %-10.10s %-s", lcntr, objline, sourceline);

would properly line up the text in columns. Note the use of a maximum field width to keep an "objline" of length > 10 from misaligning the source statements on the report. Any object code beyond the first 10 characters from "objline" simply does not appear on the assembler output report. Note that the assembler statement

MESSAGE BYTE C'THIS IS A MESSAGE' produces the 34 hex characters of object code "544849532049532041204D455353414745" in "objline" but only the first 10 are put on the assembler report. scanf, fscanf, sscanf, hscanf As discussed in Section 2.2, "scanf" (and "fscanf" and "hscanf") should be avoided. If the deformatting provided by "scanf" is needed, use "gets", "fgets", or "hgets" in conjunction with "sscanf" instead of "scanf" (or "fscanf" or "hscanf"). Even here, it should be noted that almost all deformatting requirements are taken care of by use of "atoi" and "strtol" as exhibited in dealing with "START 100" above. The "*scanf" functions are the inverse of the "*printf" functions. Input text is deformatted back into variables. The variables must be presented by addresses. Except for string variables or pointers, this means that the variable name should be preceded by "&". Normally, it should not be necessary to process more than one variable in a "*scanf" application. The deformatting syntax is borrowed from "*printf" as follows: d - deformat as an integer in decimal

x - deformat as an integer in hex s - deformat as a character string c - deformat as a single character

Page 26: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 25 of 44 For example, in /* char s[81]; int i */

sscanf(s, "%x", &i);

the string "s" is deformatted under the assumption it represents a hex integer, the integral result being placed in the variable "i". Leading "white space" (special characters, blanks) is skipped. A major difference between

scanf("%s", s); and

gets(s); is that any leading spaces in the input are ignored by "scanf", but included by "gets". FILE, fopen, fclose "FILE" is a "typedef" generated by #include <stdio.h>

Pointer variables of type "FILE" are needed by "fopen", "fputs", "fprintf", "fgets", "fscanf", and "fclose". The "fopen" routine is used to provide a link between a Unix file and a FILE pointer. Once opened, a Unix file is subsequently referenced via the file pointer. Typical open sequences are as follows: /* FILE *fnum1, *fnum2, *fnum3; */

fnum1 = fopen("outfile", "w"); /* "w" = open for output */ fnum2 = fopen("infile", "r"); /* "r" = open for input */ fnum3 = fopen("xfile", "a"); /* "a" = open for append */

The 1st "fopen" causes the Unix file "outfile" to be created if it does not exist in the user's file space. If it already exists, it is restarted afresh and all existing data in it destroyed. Data can be sent to the file using "fputs" or "fprintf" in conjunction with the FILE pointer "fnum1". The 2nd "fopen" is for reading from an existing Unix file ("infile") in the user's file space. Data can be retrieved from the file using "fgets" or "fscanf" in conjunction with the FILE pointer "fnum2". The 3rd "fopen" is for appending output to an existing file, or for creating it if it does not exist. In this case, "fputs" or "fprintf" are used in conjunction with the file pointer "fnum3" (Remark: this is the technique used by the "h" functions). The file name and/or open specification can, of course, be supplied in string variables. If an open fails, "fnum1" or "fnum2" or "fnum3" is set to NULL which can be checked; for example, if (fnum1 == NULL) exit(1);

else if (fnum2 == NULL) exit(2); else if (fnum3 == NULL) exit(3);

causes a return to Unix with the appropriate "exit" value in the event of an open failure. The exit status of a program is stored in the shell variable "$?". It can be exhibited by the command echo $?

Page 27: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 26 of 44 The syntax of "fclose" is simple; for example,

/* FILE *fnum; */ fclose(fnum);

closes the file designated by "fnum" as established in an "fopen" statement. atoi, strtol Converting numeric variables to formatted text is most easily accomplished by using one of the "-printf" functions. The most general way to accomplish the reverse process is by using one of the "-scanf" functions. However, unless unavoidable, it is generally advisable to stay away from the "-scanf" functions. For COP 3601, in particular, the simpler conversion routines "atoi" and "strtol" usually suffice. "atoi" is particularly simple; for example,

/* int i; char s[41]; */ i = atoi(s);

is all that is required to convert string "s" to an integer where "s" is assumed to be in decimal integer format. "strtol" is more complicated, and can convert from any base. For a string "s" holding a single formatted decimal integer

i = strtol(s, NULL, 10); will accomplish the same conversion as does "atoi". For a single formatted hexadecimal integer in "s", the form

i = strtol(s, NULL, 16); accomplishes the desired conversion. The hexadecimal digits > 9 can be represented either by a,b,c,d,e,f or A,B,C,D,E,F. These constructions are useful in writing an assembler when dealing with constructions such as

TABLE RESW 36 for which the formatted decimal integer "36" must be converted or

BEGIN START 10A0 for which the formatted hexadecimal integer "10A0" must be converted.

Page 28: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 27 of 44 Remark: Don't confuse this conversion process with the automatic character to integer to character conversion done in C. For example,

/* int i; char c; */ i = 'a'; c = i;

installs the ASCII representation of 'a' in "i" (hex 61); when "i" is assigned to "c", the process is reversed and the value of "c" becomes 'a'. In contrast,

i = atoi("a"); converts the string "a" to the integer 10 (which is A16). strcat, strcmp, strcpy, strlen Recall that a character string in C is simply a 1-dimensional array of characters where the end of the string within the array is marked by the string terminator character '\0'; for example, the string constant

"hello" is handled as an array of the characters 'h','e','l','l','o','\0'. The length of a string can vary within the limits of the array size based on where the string terminator character '\0' is located. Since C does not provide any operations for processing an array as a unit, functions must be used for such basic actions as assigning a string constant to a variable ("strcpy"), comparing two strings ("strcmp"), joining two strings together ("strcat"), and determining the string length ("strlen"). Assignment to a string variable (strcpy) An assignment statement such as [ s = "hello"; ] is not permitted in C. The function "strcpy" accomplishes this task; for example,

/* char s[81]; */ strcpy(s, "hello");

fills s[0],s[1],s[2],s[3],s[4],s[5] with 'h','e','l','l','o','\0'. The rest of "s" remains unaffected. Note that the character assignment

s[0] = '\0'; is a valid assignment which renders "s" into an empty string, even though the rest of the array "s" is unchanged. "strcpy" returns a pointer to the first character of "s"; in practice this returned value is seldom used. Remark: "strcpy" does not check to see if "s" is big enough to hold the whole string; if it is not, something else may be unintentionally overwritten (see Section 2.2).

Page 29: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 28 of 44 Comparing two strings (strcmp) The function usually used to compare two strings is "strcmp"; for example,

/* char s[81], t[81]; */ if ( strcmp(s, "yes") != 0 )

{ printf("\ns = %s", s);

} "strcmp(s, t)" returns a value <0 if the string "s" is lexicographically less than "t" (precedes it in dictionary order), 0 if they are equal, and a value >0 if "s" is lexicographically greater than "t". Note that the code

if ( !strcmp(s, t) ) {

printf("s and t are equal"); }

is a shorthand way to test equality of strings (recall 0 represents 'false' and anything not zero represents 'true'). Joining two strings together (strcat) Concatenation of strings is a fundamental string operation, accomplished in C usually by use of the function "strcat"; for example,

/* char objline[121], opcode[3], operand[7]; */ strcpy(objline, opcode); strcat(objline, operand);

If the string "opcode" has the contents '3','B','\0' and the string "operand" has the contents 'A','0','1','2','\0', then "3B" is first copied to "objline" and then "A012" is concatenated onto "objline". The resulting contents of "objline" are '3','B','A','0','1','2','\0' (i.e., "3BA012"). This function is obviously useful in constructing report lines, or as in the above case, a piece of object code in the assembly process. As with "strcpy", "strcat(s, t)" returns a pointer to the first character of "s"; the returned value is usually ignored. Determining the length of a string (strlen) An example employing "strlen" in generating the ASCII representation of the contents of a string was given at the start of this section. The syntax of "strlen" is simple; for example,

/* int i; char s[81]; */ i = strlen(s);

returns the length of the string "s" into the integer "i".

Page 30: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 29 of 44 strtok For writing programs which must decompose strings into their various components, it is very useful to become thoroughly acquainted with the string tokenizing function "strtok". For example, suppose the text between the single quote marks for the following needs to be extracted: MESSAGE BYTE C'THIS IS A MESSAGE'

Assuming the string variable "sourceline" holds the text, the solution using "strtok" is

/* char sourceline[81], workingstring[81], *ptr; */ strcpy(workingstring, sourceline); ptr = strtok(workingstring, "'"); ptr = strtok(NULL, "'"); printf("\nThe text is %s", ptr);

Some explanation is obviously required. In general, "strtok(s, delim)" scans the string "s" to the first character not in the string "delim" and sets the return value to the address of this character. It then continues to scan until a character in "delim" is found, replacing it with '\0'. For the above example, the first call to "strtok" then leaves "ptr" pointing to the string "MESSAGE BYTE C". Note that "strtok" actually modifies the contents of the array "workingstring", replacing the single quote character with '\0'. For this reason, as illustrated in this example, "strtok" should typically be used on a working string rather than actual data. If "strtok" is called against a NULL pointer, it resumes the previous scan from the point at which it left off. "strtok" will not cross the string terminator character '\0' (the end of the original string), so once "strtok" reaches the end of the string, all subsequent calls using NULL simply return a NULL pointer. A typical sequence for decomposing a line of assembly code such as

LOOP LDA TABLE,X

into components might be

/* char sourceline[81], workingstring[81], *ptr; char token1[81], token2[81], token3[81], token4[81]; */ strcpy(workingstring, sourceline); if (workingstring[0] == ' ')

{ token1[0] = '\0'; if ((ptr = strtok(workingstring,@ ,@)) != NULL) strcpy(token2,ptr);

} else

{ if ((ptr = strtok(workingstring,@ ,@)) != NULL) strcpy(token1, ptr); if ((ptr = strtok(NULL,@ ,@)) != NULL) strcpy(token2, ptr);

} if ((ptr = strtok(NULL,@ ,@)) != NULL) strcpy(token3, ptr); if ((ptr = strtok(NULL,@ ,@)) != NULL) strcpy(token4, ptr);

Page 31: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 30 of 44 Note that if the label component (e.g., LOOP) on the assembly language statement is not present, "token1" is set to the empty string, so regardless, "token2", "token3", and "token4" receive the op code, operand, and qualifier components of the line of assembly code being decomposed. The large sizes allocated to the token variables are predicated on the fact that "strcpy" could easily overrun one of them if the text being scanned is not a normal source line. Type checking It may be desirable for an assembler source statement such as

DEV BYTE X'F1'

to check the data between the quote marks as to its type. This is accomplished by using "isxdigit" character by character on the data; e.g., i=0;

while (isxdigit(data[i])) i++; if (strlen(data) != i) ...

The type checking functions are "isdigit" is similarly used to test if a character is a decimal digit. 2.5 The C Preprocessor Statements prefaced with "#" are preprocessor commands. The most commonly used of these are #DEFINE and #INCLUDE. #DEFINE is used to specify macro definitions. When a macro name is encountered in preprocessing the source program, the preprocessor replaces it as directed by the macro definition. By convention, preprocessor macros should be in all capital letters (NULL, FILE, DEBUG for example). #INCLUDE is used to insert external files into programs, usually to incorporate commonly needed items such as extern declarations of C library programs, standard #DEFINE macro definition statements, typdefs to be utilized in more than one module, and the like. When < > brackets are used, the preprocessor looks in the system include library (/usr/include) where the system include files are located. Sometimes what appears to be a C function is in fact a preprocessor macro to generate code in place (as opposed to a function call). The preprocessor commands

#include <stdio.h> #include <string.h> #include <ctype.h>

are among the most commonly used, and bring in macro definitions and function "extern" specifications needed by C library routines for I/O, strings, and type checking. A Unix command such as cat /usr/include/stdio.h

will exhibit the contents of a system include file and provide many examples of macro construction.

Page 32: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 31 of 44 The preprocessor command

#include "cop3601.h" brings in a locally defined include file. The "cop3601.h" include file consists of

/****************************************************/ /* University of North Florida */ /* College of Computer and Information Sciences */ /* Charles Winton */ /* email:[email protected] */ /* http://www.unf.edu/cocse/cis/cwinton/index.html */ /* */ /* Include file for COP 3601: Intro to Sys Software */ /****************************************************/ /* The "h" functions (hprintf, hputs, hscanf, and hgets) operate exactly like their standard counterparts except that they "echo" to a system file named hlib.log (created if not present, appended to, if present). The h functions capture a transcription of the screen I/O produced by the user program. An alternative is to use the Unix "script" command, which records the terminal session; however, the script command causes everything to be recorded until scripting is ended (with the h functions, what is recorded is under program control). The library of h functions, hlib, is available in /user/public/cop3601/cwinton/. To use the h functions, the program should have the include line #include "cop3601.h" and point the cc command to hlib; e.g., cc <user-prog>.c hlib */ extern int hscanf(); extern int hprintf(); extern char *hgets(); extern int hputs(); extern int happend(); extern int getline(); /* simple DEBUG facility Intent: replace printf statements installed for testing purposes with the construction DEBUG(printf( . . .);) Activate/deactivate by installing/removing #define TESTING as line 1 of the source code NOTE: under "vi" the DEBUG statements can be removed by executing the "ex" command :%s/<srch-pat>// where <srch-pat> is DEBUG(.*

Page 33: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 32 of 44

<srch-pat> is the string "DEBUG(" followed by 0 or more characters. Note: :set magic (which is the system default) must be in effect for this to work */ #ifdef TESTING #define DEBUG(x) printf("DEBUG: "); x #else #define DEBUG(x) #endif

To see the expanded C code after the preprocessor has been invoked use either

cc -E myprog.c > temp or

cpp myprog.c > temp Only the preprocessor is run in either case, the result sent to standard output. In the above, it has been redirected to "temp" from which it can be examined at leisure.

Page 34: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 2 (Using C) - Page 33 of 44 2.6 C programming style Do not use "go to". Use the naming conventions:

All caps = a preprocessor macro call First letter capitalized = a global variable To make a long variable name more interpretable, use the underscore

character ('_') as a separator Improve appearance by using one of the recognized styles for C programs (these are given on the web)

Observe

POOR: for(i=1+tabsize;i>0&&i<=check;i--)checktab(i);

OK: for(i=tabsize+1; i>0 && i<=check; i--) checktab(i);

BEST: for(i = tabsize + 1; (i > 0) && (i <= check); i--) {

checktab(i); }

and try to use the "BEST" style. Each routine should at a minimum have a leading comment briefly explaining its purpose, the nature of its parameters, and what it will return (if any); for example,

int print_as_column(char s[]) { /* Purpose: output string s as a vertical column on the display Parameters: s = the string to be displayed Returns: the number of characters output */ int i, leng; leng = strlen(s); for (i = 0; i < leng; i++) { printf("%c\n", s[i]); } return(leng); }

Page 35: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 3 (Unix Libraries; Make) - Page 34 of 44

Chapter 3

Unix Utilities: Object Module Libraries and Make Files The basic UNIX utility for processing libraries is the archiver "ar". Assume you have some C source modules; for example, as follows:

main.c, globals.c, sub1.c, sub2.c (example source listings are given in Section 3.7) 3.1 Creation of a library Compile the modules to go in the library, suppressing link-edit; e.g.,

cc -c globals.c cc -c sub1.c

The object modules will be stored in "globals.o" and "sub1.o". Archive the object modules in your library; e.g.,

ar -r my.clib globals.o sub1.o 3.2 Updating or adding to a library The same "ar" option ("-r") used above for creation accomplishes this; e.g.,

cc -c sub2.c ar -r my.clib sub2.o sub2.c

If "sub2.o" or Asub2.c@ is already in the library, the new version replaces it. 3.3 Obtaining a table of contents for a library

ar -t my.clib

Page 36: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 3 (Unix Libraries; Make) - Page 35 of 44 3.4 Deleting a library entry

ar -d my.clib sub2.c

removes the module "sub2.c" from the library "my.clib". 3.5 Using a library Routines are typically linked in from a library as part of the "cc" command sequence. For example, each of the following command sequences generates the same execute module "a.out":

1. cc main.c sub1.c sub2.c globals.c (compile and link all modules)

2. cc main.c my.clib

(compile "main.c", link other modules from a library)

3. cc -c main.c (compile "main.c" without linking)

cc main.o my.clib

(compile nothing, link listed ".o" modules and other modules from a library) 3.6 make Files make is a Unix utility program that is used to manage the various tasks associated with processing a group of programs and files comprising a software system. For example, a simple change in a header file will usually require recompilation of all programs that are dependent on it. The make utility provides means for automating tasks such as this. A Amake file@ is a user file that contains specifications for the utility to employ in accomplishing tasks of this sort. The make utility is invoked by executing

make or

make -f <makefile-name> If the -f option is not used, the system first looks for a file named "makefile", then "Makefile", then other names as described by the man page for make for the Unix implementation. Rather than use the -f option, programmers often just go with the basic default and build their project make file in a file named "makefile". A make file is composed of a sequence of sections, each of which is headed by a line that names one or more Atarget@ files and the files that they are dependent on, plus additional lines that stipulate the Aconstruction commands@ to be executed to update the target file. Each of the lines stipulating construction commands must be preceded by a <TAB> character. For example, the following is a make file for the set of programs given in Section 3.7:

Page 37: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 3 (Unix Libraries; Make) - Page 36 of 44

exprog: sub1.o sub2.o globals.o cc main.c sub1.o sub2.o globals.o -o exprog

sub1.o: sub1.c

cc -c sub1.c

sub2.o: sub2.c cc -c sub2.c

globals.o:

cc -c globals.c Any target can be "made" by entering make <target> If make is entered at the Unix prompt, the make utility will execute those construction commands necessary to bring all dependencies Aup to date@; e.g., if sub2.c has been changed (but nothing else), the make utility will execute the construction commands for sub2.o since exprog is dependent on sub2.o followed by the construction commands for exprog in order to bring exprog up to date; i.e.,

cc -c sub2.c cc main.c sub1.o sub2.o globals.o -o exprog

In the absence of an expressed dependency, the make utility correctly assumes the ".o" file depends on a source code file and so supplies it. In fact, the only section required in the make file is

exprog: sub1.o sub2.o globals.o cc main.c sub1.o sub2.o globals.o -o exprog

since the make utility will assume that any dependencies which are ".o" files have a corresponding source file that will need to be recompiled if not current. If there are source files for more than one compiler present, it is advisable to explicitly provide all dependencies in the make file. Generally, any ".o" file lacking a rule (ie., there is no target whose name is that of the ".o" file) is handled by using an implicit rule. make will correctly infer that the ".o" file is dependent on the corresponding ".c" file. If the ".o" file is dependent on files not requiring a construction command, a rule for the ".o" file that specifies these, but which omits any construction commands should be used to supply the additional dependencies needed. This kind of complication can be avoided by just supplying the rules for each ".o" file explicitly. If a target has no dependencies, and it is a file name, it is automatically “up to date” (another reason to avoid implicit rules). If the target name is not a file name, its construction commands will automatically be executed (see the example, make clean below).

Page 38: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 3 (Unix Libraries; Make) - Page 37 of 44 The make utility includes a macro facility, which at its simplest level has the form: <macroname>=<replacement-list> e.g., CC=gcc where the replacement is invoked by $(CC) An elaboration of the make file given above using simple macros is: CC=gcc CFLAGS=-g

exprog: sub1.o sub2.o globals.o $(CC) $(CFLAGS) main.c sub1.o sub2.o globals.o -o exprog

sub1.o: sub1.c

$(CC) $(CFLAGS) -c sub1.c

sub2.o: sub2.c $(CC) $(CFLAGS) -c sub2.c

globals.o:

$(CC) $(CFLAGS) -c globals.c clean: rm exprog rm *.o Changing "CFLAGS=-g" to "CFLAGS=" causes compilation without the "-g" option. By specifying the target "clean"; e.g. make clean the executables generated by using the make file are deleted. The Unix "touch" command will update the listed modification time for a file to be the current time. This is useful for forcing the make utility to recompile one or more programs; e.g., touch sub2.o will force the make utility to recompile exprog. touch sub2.c will force the make utility to recompile sub2.c as well as exprog. Executing make -t will cause the make utility to touch all relevant files rather than process them. In effect, this causes the make utility to consider everything to be up to date, which is useful, for example, in a case where a file was first altered and then subsequently restored, so recompilation is not needed. Remark: dependencies may include files (such header files) that do not explicitly appear in any of the construction commands.

Page 39: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 3 (Unix Libraries; Make) - Page 38 of 44 3.7 Example listings of C program modules Remarks: One module needs to contain the routine "main()". Modules can consist of any combination of routines and external variables. main.c: [the module containing the routine "main()"] #include <stdio.h>

main() {

extern int x; extern char y[]; sub1(); sub2(); printf("\nx=%d, y=%s\n",x,y); exit(0);

} globals.c: [a module consisting of external (global) variables visible to any module declaring

them as "extern"] int x=15;

char y[10]="example"; sub1.c: [a module containing a subroutine] #include <stdio.h>

sub1() {

printf("\nsub1"); }

sub2.c: [a module containing a subroutine] #include <stdio.h>

sub2() {

printf("\nsub2"); }

Facsimile output generated by compile and execute of the above modules: $cc main.c globals.c sub1.c sub2.c [compile and link (order unimportant)] main.c: [each module name is output as globals.c: the compiler begins compiling it] sub1.c: sub2.c: $a.out [execute] sub1 [program output] sub2 x=15, y=example $

Page 40: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 4 (Using gdb) - Page 39 of 44

Compilation format: Format for invoking gdb:

cc -g prog.c ........ ........... ........... gdb a.out or

cc -g prog.c -o prog .. ........... gdb prog

Chapter 4

Using the Source Debugging Program gdb

The available source language debugging programs provided within a Unix installation vary according to the version of Unix being used. Unix System V provides a debugger called sdb. Under Berkeley Unix, the debugger is called dbx (a cruder predecessor, adb, may also be present). Under Linux, the debugger is called gdb. All of these debuggers have similar syntax and capabilities. gdb is discussed in this chapter since it is one of the more universally available variants. Source line debugging is not fully enabled by the C compiler unless cc is executed with the A-g@ option. A full reference on an installed debugger, whether gdb, dbx, sdb, or adb is contained in the debugger=s man page. 4.1 Uses

1. To determine what caused a "core dumped" message in program execution 2. To single step a program, or execute it to a specified break point, to isolate logic errors Remark: You must have a clean compile to use gdb - use compiler diagnostics or "lint"

to correct compile time errors. 4.2 Starting gdb

gdb can also be started just by entering gdb

(in which case the user must specify the execute file name using the "file" command).

If ASegmentation fault(core dumped)@ occurs, the core file can be provided to gdb by entering

gdb <name> core<seq#> Starting gdb with the -q option suppresses the lengthy lead-in message; e.g., gdb -q prog 4.3 Exiting gdb

Enter q

at the "(gdb)" prompt to quit gdb.

Page 41: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 4 (Using gdb) - Page 40 of 44 4.4 Basic examples

Example 1: Locating a source line that causes a core dump NOTE: you may need to execute ulimit -c unlimited from the command prompt for core dumps to be generated (they consume significant space)

Terminal session facsimile

By starting gdb with the command line gdb -q a.out core both the execute file for the program and the current core file generated by the program=s execution are passed in to gdb for analysis, which identifies line 5 as the point of execution where the fault occurred. The "list" command line (abbreviated by "l") is used to list lines from the current source file. The user can specify

1) the procedure to list a window 10 lines around its header line 2) the source line of the active procedure to list a window of 10 lines around 3) the range of lines to list ("l <x>,<y>") 4) the source file and line(s) ("l <source-file>:<x>")

If there is no operand, the default is to list 10 lines forward from the current list position.

$ cat -n check.c 1 main() 2 { int *p; 3 p=0; 4 printf("This program forces a core dump:\n"); 5 printf("%d\n",*p); 6 printf("\nLine after forced core dump\n"); 7 exit(0); } $ cc -g check.c $ a.out This program forces a core dump: Segmentation fault(core dumped) $ gdb -q a.out core Core was generated by `a.out'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/libc.so.6...done. Loaded symbols for /lib/libc.so.6 Reading symbols from /lib/ld-linux.so.2...done. Loaded symbols for /lib/ld-linux.so.2 #0 0x8048463 in main () at check.c:5 5 printf("%d\n",*p); (gdb) l 1 main() 2 { int *p; 3 p=0; 4 printf("This program forces a core dump:\n"); 5 printf("%d\n",*p); 6 printf("\nLine after forced core dump\n"); 7 exit(0); }

(gdb) q

Page 42: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 4 (Using gdb) - Page 41 of 44

$ cat -n prog2x.c 1 main() 2 { int *p; 3 p = 0; 4 sub1(p); 5 exit(0); } 6 sub1(x) 7 int *x; 8 { int *p; 9 p = x; 10 sub2(p); } 11 sub2(x) 12 int *x; 13 { int *p; 14 p=x; 15 printf("This program forces a core dump:\n"); 16 printf("%d\n",*p); 17 printf("\nLine after forced core dump\n"); } $ cc -g checkx.c $ a.out This program forces a core dump: Segmentation fault (core dumped) $ gdb -q a.out core Core was generated by `a.out'. Program terminated with signal 11, Segmentation fault. Reading symbols from /lib/libc.so.6...done. Loaded symbols for /lib/libc.so.6 Reading symbols from /lib/ld-linux.so.2...done. Loaded symbols for /lib/ld-linux.so.2 #0 0x80484b6 in sub2 (x=0x0) at checkx.c:16 16 printf("%d\n",*p); (gdb) where #0 0x80484b6 in sub2 (x=0x0) at checkx.c:16 #1 0x804848c in sub1 (x=0x0) at checkx.c:10 #2 0x8048459 in main () at checkx.c:4 #3 0x4003a0ea in __libc_start_main (main=0x8048440 <main>, argc=1, (gdb) q

Example 2: Interpreting a stack trace

Terminal session facsimile

In this case a "stack trace" is produced by the "where" command showing that the core dump occurs within a subroutine 2 levels down from main. It shows that:

"sub2" is at line 16 of source file "checkx.c" with its parameter "x" = (NULL), called from

"sub1" at line 10 of "checkx.c" with its parameter "x" = (NULL), called from

"main" at line 4 of "checkx.c".

Page 43: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 4 (Using gdb) - Page 42 of 44

$ gdb -q a.out (gdb) list 1,11 1 main() 2 { int n; 3 n = 2; 4 sub1(n); 5 exit(0); } 6 sub1(x) 7 int x; 8 { int n; 9 n = x+3; 10 printf("%d\n",n); 11 } (gdb) break 10 set a breakpoint at line 10 Breakpoint 1 at 0x8048483: file checky.c, line 10. (gdb) run execute to the breakpoint Starting program: /var/public/cop3601/cwinton/gdbdemo/a.out Breakpoint 1, sub1 (x=2) at checky.c:10 10 printf("%d\n",n); (gdb) print n value of n in sub1 $1 = 5 (gdb) cont resume execution 5 Program exited normally (gdb)

4.5 Running a Program from gdb

Example 3: Executing a working program from within gdb Terminal session facsimile

The command break 10 sets a break point at line 10. The terminal response shows the break point is set and that it is in sourcefile "checky.c". "break" can be abbreviated by "b". The command

run

then executes the main procedure, execution halting at the break point. "run" can be abbreviated by "r".

print n

causes the current (local) value of the program=s variable n to be displayed. print can be abbreviated by p.

cont

causes execution to resume from the break point. The break point remains in place until removed. cont can be abbreviated by c.

Page 44: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 4 (Using gdb) - Page 43 of 44

If a section of code is bad, the "jump" command (or "j") can be used to bypass it; e.g., in example 2 when stopped by Abad@ code on line 16,

j 17

would continue execution on line 17.

To cause the program to "single step" a line of source code enter next

next can be abbreviated by n. The variation

next 10

causes the program to execute the next 10 lines and then halt again. 4.6 Setting/Unsetting Break Points As already noted, break points can be set by using line numbers with the command "break".

They can also be set symbolically; e.g.,

break sub1

sets a break point at the first line of the function "sub1". "break" can be abbreviated by "b".

info break

causes all break points currently set to be listed (abbreviated by "i b").

delete 3

removes the break point numbered 3;

delete

removes all break points. "delete" can be abbreviated by "d".

4.7 Examining/Changing Variable Values

When executing a program within gdb or when dealing with a core dump, variable values can be examined at the point execution halted. Simple variables can be examined as in Example 3. This applies equally to more complex structures. For example,

print name1[2][4]

displays a component of a 2-dimensional array "name1"; print name2.qual

displays the "qual" component of the structure "name2";

Page 45: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Chapter 4 (Using gdb) - Page 44 of 44

print *name3

displays the value pointed at by the pointer variable "name3".

Output can also be formatted similar to the "printf" library function of C; e.g.,

printf "%d\n%d",m,n

shows the values of the (integer) variables m and n formatted as per the "%d" specification and displayed on consecutive lines.

If program execution is initiated from within gdb, variable values may be changed whenever the program is halted by using the "print" command. When execution is resumed, the new values will be the ones in effect. For example, (code taken from Example 3 above), the sequence

(gdb) break 10 Breakpoint 1 at 0x8048483: file checky.c, line 10. (gdb) run Starting program: /var/public/cop3601/cwinton/gdbdemo/a.out Breakpoint 1, sub1 (x=2) at checky.c:10 10 printf("%d\n",n); (gdb) list 9,11 9 n = x+3; 10 printf("%d\n",n); 11 } (gdb) print n show the value of n $1 = 5 (gdb) print n=23 assign a new value to n $2 = 23 (gdb) print n show the new value of n $3 = 23 (gdb) cont resume execution (printf Continuing. gets the new value) 23 Program exited normally. (gdb)

shows that using the "print" command to change the value of the variable "n" to 23 changes the outcome of the subsequent printf statement in the program. This facility is useful, for example, for probing a subroutine=s response to different parameter values.

Page 46: Systems Supplement for COP 3601 - University of North Floridacwinton/html/cop3601/supplements/sys-supp.… · COP 3601: Introduction to Systems Software Charles N. Winton Department

Appendix (.vimrc) - Page i

Appendix Sample .vimrc file " use vim options, not those of vi set nocompatible " allow backspacing over everything in insert mode set backspace=indent,eol,start " indent based on previous line set autoindent " for program code indent intelligently set smartindent " set TAB amount to 4 spaces set tabstop=4 " indent amount 2 set shiftwidth=2 " when closing block briefly show block opener set showmatch " don't highlight search matches set nohls " search incrementally as text is entered set incsearch " show line numbers, indicate mode at bottom set number showmode " require use of \ when searching for metacharacters set nomagic " for search ignore case, unless there is a capital letter in the string set ignorecase smartcase " keep a couple of lines around the cursor for determining context set scrolloff=2 " configure for C system settings set syntax=c filetype=c makeprg=vgcc


Recommended