程序代写代做代考 data structure chain compiler file system assembly assembler C Programs in Unix

C Programs in Unix
CSci4061: Introduction to Operating Systems

September 14, 2021
Computer Science & Engineering, University of Minnesota
1

Announcements
• Next lecture on Thursday will be online, with a recorded video • Teaming: 09/16
• Final exam: 4pm-6pm 12/16/2021
• Ethics on security research to be covered in the security topic
2

Last lecture
• OS evolution
• How does the OS prevent accesses from malicious applications? • How do applications get access to desired resources?
• Syscall and libraries
• Unix shell
• Unix file system
3

This lecture
• C program structure
• Components of C programs
• Compiling and building programs • Executing a program
• Testing and debugging
4

C program (source) structure

A “hello world” C program
// Use library ‘stdio’
#include
// Program start point; commend line arguments: argv[] int main(int argc, char *argv[])
{
// Call printf to print out message
if (argc > 1)
printf(“%s\n”, argv[1]);
else
printf(“Hello World\n”);
// Return a number: 0: success, -1: error return 0;
}
5

Elements in a C program
6

Elements in a C program
Set of types/data structures, variables (data), and functions (code)
• Types: structs, unions, basic types, function types
• C does not have “string” type
• typedef char * c_string • Variables:
• Local: Visible within the current single function • Static: Visible to all functions within a file
• Global: Visible in all functions across files
• Functions:
• User-defined or library functions
6

Function main()
int main(int argc, char *argv[])
• main is the program starting point • Is it the real entry of a program?
• What are argc and argv?
7

Function main()
int main(int argc, char *argv[])
• main is the program starting point • Is it the real entry of a program?
• What are argc and argv?
– `argc`: number of command-line arguments
– `argv`: array/vector of command-line arguments
– What are the values of `argc` and `argv` in the following cases:
./hello
./hello csci4061
7

Standard program work-flow
• Parse the command line
• Check for syntax and extract various options
• Report error/usage if ill-formed command line
• Do the desired execution
• Read files, run threads, write output, etc.
• Cleanup and exit
• Free all resources • Exit gracefully
• Handle errors and print error msg • Return proper error code
Note: All these are developer’s job in C!
8

Components: Libraries, header and source files

Files in C programming
• Header files (.h) • Source files (.c) • Libraries
• Static (.a in Unix) and dynamic (.so in Unix) • Difference?
9

Header files (.h)
• Define types, function prototypes, constants, macros • Define elements that are shared across modules
• Include the header file when using its elements
• Define the interface exposed to external programs
• E.g.: library header files
• Default include path: /usr/include Q: Why do we need header files at all?
10

Source files (.c)
• Contain include statements for header files to include global declarations and prototypes
• Contain implementation code of the functions of the program
• May contain static variables that are required only in that source file
#include
#include “decls.h”
// static variable
int static_var = 0;
void foo() {
// do something
}
11

Libraries
• Utility functions/system calls
• Pre-installed on the system
• Prototypes of functions called from program must be declared
• Include appropriate header files
• To include the string library: #include
• Where are libraries?
• Standard libraries: /usr/lib/ and /lib/
• Custom libraries: may have to be linked at compile time
• -L{path to file containing library} -l${library name}
• E.g., gcc -o hello hello.c -L/home/kjlu/lib -lmine
• The linker will search “libmine.so” or “libmine.a” in “/home/kjlu/lib/”
12

Programming commandments
• Thou shalt write readable code
• Thou shalt use lot of documentation • Thou shalt use good coding style
• Comments, indentation, space
• Meaningful variable/function names
• E.g.: sort_list() instead of foo()
• E.g.,: buf_size instead of v1
• Use named constants (macros) instead of concrete numbers
• E.g.: MAXLEN instead of 1024
• Modular: put unrelated functions in separate files • Proper error handling
GNU Coding Standards for C: https://www.gnu.org/prep/standards/html_node/Writing-C.html 13

Error handling
What’s wrong with the following code?
1. int fd, sz;
2. char *c = (char *) calloc(100, sizeof(char)); 3. fd = open(“foo.txt”, O_RDONLY);
4. sz = read(fd, c, 10);
5. close(fd);
14

Error handling
What’s wrong with the following code?
1. int fd, sz;
2. char *c = (char *) calloc(100, sizeof(char)); 3. fd = open(“foo.txt”, O_RDONLY);
4. sz = read(fd, c, 10);
5. close(fd);
Check “c” and “fd”, and handle potential errors
14

Error handling
1
2
3 4}
• Capture errors: If a function can return an error, check for it
• Check for every possible error, even if rare
• Almost always check library calls and system calls for errors! • Return error codes: Return values from your functions
• Error codes on error
• C convention: negative numbers for errors; zero for success
• Do not exit abruptly from your functions • Exit gracefully from main()
• Handle errors: error messages, fixing, exiting
• E.g.: perror(), exit()
if (close(fd) == -1) {
perror(“Failed to close the file”); return -1;
15

Compiling and building programs

Toolchain in program compilation
• Preprocessor: Processes statements, macro and constant definitions • Compiler: Converts source code into assembly code
• A preprocessor is the front-end of a compiler
• Assembler: Converts assembly code into machine language
• Linker: Combines multiple object files into executable program
16

Program compilation
Program Compilation
14
17
hello.c
#include #define MAXLEN 1024
void print_msg() {
char *msg=“Hello World”;
printf(“%s\n”, msg); }
Compiler hello.s
hello.o
01110010100 0111…..
Object files, Libraries
Print_msg: store this load that push register .
. .
Assembler
Linker
hello

Program compilation: make
• ‘make’ builds programs by using dependency trees
• Makefile allows multiple program dependencies to be specified in a file
• If a source/header file changes, make recompiles dependent targets recursively
:

A simple Makefile:
hello: hello.o
gcc -o hello hello.o
hello.o: hello.c
gcc -c hello.c
18

ELF binary—ELF header
readelf -a hello
19

ELF binary—ELF sections
20

Executing a program

Program execution
Runtime execution of a program depends on
• Program arguments
• Environment variables
• Dynamic libraries
• Other programs and the operating system
21

Program arguments and environment
• Command-line arguments:
• argc, argv
• Environment variables:
• Associated with each program
• Typically determined by the invoking shell environment
22

Dynamically linked libraries
• Static vs. dynamic linking
• Statically linked libraries are linked into the executable at compile time
• More independent but any disadvantages?
• Dynamically linked libraries are loaded when the program is started
• Done by loader ld.so
• But ld.so itself is a dynamic library?
• System must be able to find dynamic libraries at runtime
• $LD_LIBRARY_PATH
• Default: /lib, /usr/lib
23

Other programs and Operating System
Other programs impact your program in several ways:
• Communication
• Sharing of data
• Affect performance
Operating system:
• Provides all the low-level services and utilities • Manages resources for your program
• E.g., scheduling
• Provides security and isolation
24

Testing and debugging

Testing
How did you check/test your code?
25

Testing
How did you check/test your code?
• Manual code auditing/review
• Static analysis
• Dynamic analysis
• Sanitizers—potential vulnerabilities
• Such as AddressSanitizer
$ gcc -g -fsanitize=address hello.c -o hello
25

Debugging
• Iterative process • Using printf()?
• Track variables, functions by printing out useful information • Edit, recompile, run to get additional info
• Turn debugging on/off using compiler flags
#ifdef DEBUG
fprintf(stderr, “val=%d\n”, val);
#endif
26

A better way of debugging: gdb
• GNU debugger
• Allows examining the program in slow-motion with pauses and fast-forwards
(playbacks, but no rewinds)
• Set breakpoints
• Step through program • Examine variable values
• Don’t forget to use “-g” flag while compiling program to include debug information
$ gcc -g -o hello hello.c
27

Evaluating programs
• Correctness and functionality • Quantitative metrics
• Runtime
• Latency
• Throughput
• System Resource usage
• CPU time, memory, disk space, network bandwidth
• Reliability and security
28

Observing a running program
• time: Get the runtime of your program (both user and kernel time)
• $ time hello
• ps: Gives information about running programs in the system (processes)
• top: Gives resource usage information (CPU share, memory, running time,
status, etc.)
• strace: Trace system calls
29

Common problem—Missing error handling
1. int fd, sz;
2. char *c = (char *) calloc(100, sizeof(char)); 3. fd = open(“foo.txt”, O_RDONLY);
4. sz = read(fd, c, 10);
5. close(fd);
• There are many corner cases
• Functions, especially system calls and library functions can fail
• Almost always check their return values to capture and handle errors • Follow the convention for error handling
30

Common problem—Memory leak
• Dynamic memory allocation function
• void * malloc (size_t size)
1 void foo (){
2 3}
malloc(100);
4
5
6
7 8}
for (i = 0; i < 100; ++i) foo(); void main() { int i; What is the problem? 31 How to avoid memory leaks • Free objects when you are done with them • Use tools such as LeakSanitizer $ gcc -g -fsanitize=leak hello.c -o hello 32 Common problem—Buffer overflow void foo (char *str) { char buf[8]; strcpy (buf, str); } void main(int argc, char *argv[]) { foo(argv[1]); } What is the problem? What if the input string has 8 bytes? 33 Exploiting buffer overflows buffer overflow argv[1] return address saved %ebp buf grows to high address 8(%ebp) 4(%ebp) %ebp -8(%ebp) -0x10(%ebp) "top" of stack %esp -0x28(%ebp) local variables argv[1] &buf 34 How to avoid buffer overflows 35 How to avoid buffer overflows • Be careful about the null (\0) byte • Do not use: gets, strcpy, strcat, etc. • Instead, use: fgets, strncpy, strncat, etc. • Use tools such as AddressSanitizer $ gcc -g -fsanitize=address hello.c -o hello 35 Summary • Elements in a C program • Files in a C program • Compiling and building programs • Executing and debugging • Common problems • How to avoid them? 36 Next lecture • Process overview • Recorded video • Reading: Robbins 3.1 37