200 likes | 328 Views
CSC 552.201 - Advanced Unix Programming, Fall, 2008. Welcome to UNIX System Programming! Tuesday, September 2 uses Monday’s schedule!. Who am I?. Dr. Dale E. Parson (a.k.a. Professor Parson ), http://faculty.kutztown.edu/parson/
E N D
CSC 552.201 - Advanced Unix Programming, Fall, 2008 Welcome to UNIX System Programming! Tuesday, September 2 uses Monday’s schedule!
Who am I? • Dr. Dale E. Parson (a.k.a. Professor Parson), http://faculty.kutztown.edu/parson/ • In a previous life I was an AT&T technician and then a Bell Labs software engineer for over 25 years. Also, I consult as Amplified Computing. • I have taught at Albright College, Millersville University and Lehigh University.
Who are you? • Excited Kutztown University computer science grad students who want to become or may already be Unix System software engineers! • You have already taken CSC 352, UNIX: Systems Programming and Administration, or you have permission of the instructor. • This course deals with the study of the UNIX operating system, particularly systems programming and administration. Under the former, such topics as UNIX commands, filters, shell scripts, system security, user accounts, system backup and rebooting, and associated utilities are studied. In addition, software procurement, using the WWW, and installation will be illustrated. Under the latter, such topics as file primitives and directory access, system utilities, processes, signals and signal handling, inter-process communication, semaphores, file and record-locking, sockets, and terminal manipulation are studied. Meaningful applications which illustrate the topics will be examined. (Ah, this is the fine print for CSC 352!)
What are we planning to do? • We will build multi-process, multi-threaded and distributed software systems in Unix. • We will use C++ interface and module construction techniques. • The underlying building blocks are mostly C language system calls and library functions. • man –s2 write (or read, fork, exec, dup, open, close, pipe) • man –s3c fprintf (or fgets, fopen, fclose, popen) • We will not use C++ iostream in this course.
References • We start with the First Day Handout (syllabus). • gcc and g++ - http://gcc.gnu.org/onlinedocs/http://sunsite.ualberta.ca/Documentation/Gnu/gcc-2.8.1/man/gcc.1.htmlhttp://sunsite.ualberta.ca/Documentation/Gnu/gcc-2.8.1/man/g++.1.html • GNU make http://www.gnu.org/software/make/manual/ • Invoke gmake on SunOS systems. • gdb - http://www.gnu.org/software/gdb/documentation/ • Solaris - http://docs.sun.com/app/docs/coll/40.10 • Use man command for section 1 utilities such as ls and ps. • /export/home/faculty/parson/UnixSysProg on bill.kutztown.edu
An simple example makefile • makefile in UnixSysProg/lecture1 all: build TARGET = printdemo DEBUG = 1 include $(HOME)/makelib build: $(TARGET) $(TARGET): $(OBJFILES) $(CPPCC) $(OBJFILES) -o $@ clean: subclean /bin/rm -f $(TARGET) $(TARGET).out $(TARGET).dif test: $(TARGET) ./$(TARGET) a b c d e > $(TARGET).out diff $(TARGET).out $(TARGET).ref > $(TARGET).dif
makelib in my $HOME/ • makelib CPPCC= g++ CXXFILES := $(wildcard *.cxx) OBJFILES := $(subst .cxx,.o,$(CXXFILES)) DEFFLAGS = ifeq ($(DEBUG),1) DEBUGFLAG = -g else DEBUGFLAG = endif INCFLAGS = -I. CPPFLAGS= $(DEFFLAGS) $(INCFLAGS) $(DEBUGFLAG) %.o : %.cxx $(CPPCC) -c $(CPPFLAGS) $< subclean: /bin/rm -f *.o
Some other files in my $HOME/ • .bash_profile -bash-3.00$ cat .bash_profile export EDITOR=/usr/local/bin/vim export VISUAL=/usr/local/bin/vim alias vi=vim alias make=gmake • .vimrc -bash-3.00$ cat .vimrc set ai set ts=4 set sw=4 set expandtab set sta
Interface definitions split source along module / driver boundaries. • printargs.h defines the interface to its module #ifndef PRINTARGS_H #define PRINTARGS_H #include <stdio.h> /* Function: printargs Prints an array of strings to an output file. Parameters: outfile: output file for writing. stringv: array of \0-terminated strings to be printed. stringc: numbers of strings in stringv Return value: none Side Effects: none Preconditions: The outfile must be a non-NULL, open FILE. stringc must equal the number of strings in stringv. Each string in stringv must be terminated with a \0 character. Postconditions: none (no return values from this function). Invariants: none */ void printargs(FILE *outfile, const char **stringv, const int stringc); #endif
Implement the interface in a .cxx file. • printargs.cxx implements the module of printargs.h /* printargs.cxx -- Function implementations for printargs.h. CSC552, Fall, 2008, Dr. Dale Parson, Class 1 example. This is a simple demo library module that prints an array of strings to an output file. */ #include "printargs.h" void printargs(FILE *outfile, const char **stringv, const int stringc) { int i ; for (i = 0 ; i < stringc ; i++) { fputs(stringv[i], outfile); fputs("\n", outfile); } }
Invoke the interface from a client module or test driver. • printmain.cxx is the test driver /* printmain.cxx -- main function that invokes printargs. CSC552, Fall, 2008, Dr. Dale Parson, Class 1 example. This is a simple driver for a demo library module that prints an array of strings to an output file. */ #include "printargs.h" int main(int argc, const char *argv[]) { printargs(stdout, argv, argc); return 0 ; }
Makefile-driven testing • makefile is structured for testing -bash-3.00$ make clean test /bin/rm -f *.o /bin/rm -f printdemo printdemo.out printdemo.dif g++ -c -I. -g printargs.cxx g++ -c -I. -g printmain.cxx g++ printargs.o printmain.o -o printdemo ./printdemo a b c d e > printdemo.out diff printdemo.out printdemo.ref > printdemo.dif
GDB for debugging -bash-3.00$ gdb --args printdemo a b c (gdb) break main Breakpoint 1 at 0x107f4: file printmain.cxx, line 13. (gdb) break printargs Breakpoint 2 at 0x10780: file printargs.cxx, line 14. (gdb) run Starting program: /export/home/faculty/parson/UnixSysProg/lecture1/printdemo a b c Breakpoint 1, main (argc=4, argv=0xffbffc54) at printmain.cxx:13 • printargs(stdout, argv, argc); • (gdb) p argc • $1 = 4 • (gdb) p &argc • $2 = (int *) 0xffbffc34
GDB continued (gdb) cont Continuing. Breakpoint 2, printargs (outfile=0x20b20, stringv=0xffbffc54, stringc=4) at printargs.cxx:14 14 for (i = 0 ; i < stringc ; i++) { (gdb) step 15 fputs(stringv[i], outfile); (gdb) next /export/home/faculty/parson/UnixSysProg/lecture1/printdemo 16 fputs("\n", outfile); (gdb) next 14 for (i = 0 ; i < stringc ; i++) { (gdb) p i $3 = 0 (gdb) p &i $4 = (int *) 0xffbffb6c
Program Image, Sample Layout • Figure 2.1. How can we verify? gdb and /proc! high address argc/argv, env stack activation recs. return addr., params, saved registers, autos heap malloc or new uninitialized static data initialized static data low address program text
Looking inside a process • Use nm to get static layout information. • Supply C address-of operator to gdb. • /proc utilities examine process layout • pstack [ -F ] PID examines stack • pfiles [ -F ] PID examines open files • pldd [ -F ] PID examines dynamic libraries • pmap [ –xlF ] PID examines memory layout
Process status • gdb is debugging printdemo -bash-3.00$ ps -al S UID PID PPID TIME CMD O 11236 720 580 0:00 ps S 11236 569 29452 0:01 gdb T 11236 570 569 0:00 printdemo • nm -psC printdemo | sort | more • This shows symbol layout in executable printdemo.
C++ interfaces and dynamic loading • ~parson/UnixSysProg/lecture1/oo_variant • We will walk through code and test execution in class. • Important points • C++ abstract classes are used as interfaces. • Derived C++ concrete classes provide implementation. • An abstract factory method uses dynamic loading and run-time type checking (RTTI) to load a concrete derived class and its concrete factory method. • An factory method runs a constructor. • See man pages for dlopen(), dlsym() and dynamic_cast.
fork / exec / wait example code • ~parson/UnixSysProg/lecture1/forkexec • We will walk through code and test execution in class. • Important points • argc / argv command parameter usage • Use C string library to parse a command parameter. • fork()’s return value indicates parent or child PID. • getpid() returns child PID to child; getppid() gets parent. • exec() returns only on failure. • Use pmap to examine both processes.
Programming practices • Always check and handle library return codes! • malloc() and new are exceptions that we will discuss. • Error logs, exit codes and C++ exceptions are useful. • Buffer overruns are annoying and dangerous • See man page for gets(), for example. • Make malloc/free or new/delete symmetrical. • Always use { curly braces } for control blocks. • Use both healthy and degenerate tests. • Ignoring these rules will cost you points.