440 likes | 800 Views
The Environment of a UNIX Process. Introduction. How is main() called? How are arguments passed? Memory layout? Memory allocation? Environment variables Process termination. Process. A Process is program (eg., a.out) under execution in a UNIX or POSIX system.
E N D
Introduction How is main() called? How are arguments passed? Memory layout? Memory allocation? Environment variables Process termination
Process A Process is program (eg., a.out) under execution in a UNIX or POSIX system. For Example: a UNIX shell is a process that is created when a user logs on to a system. More over, when a user enters a command cat foo to a shell prompt, the shell creates a new process. In UNIX terminology, this is a child process, which executes the cat command on behalf of user. When a process creates a child process, it becomes the parent process of the child. The child process inherits many attributes from its parent process, and it is scheduled by the UNIX kernel to run independently from its parent.
Process (Cont…) It’s also possible to create multiple processes that run concurrently, an Operating system can serve multiple users and perform multiple tasks concurrently. Thus the process creation and management are the concern stone of a multi-user and multitasking operating system like UNIX.
main Function int main(int argc, char *argv[]) argc = no. of command line arguments argv[] = array of pointers to the arguments
main Function (Cont…) C program started by kernel (by one of the exec functions) Kernel executes a special START-UP routine before main() The executable program file specifies this start-up routine as the starting address for the program-this is set up by the link editor when it is invoked by the C compiler, usually cc Startup-routine Takes values from the kernel (command-line arguments and environment Start-up routine sets things up before main() is called: stack, heap, etc.
Process Termination 5 ways Normal termination: return from main() calling exit() calling _exit() Abnormal termination calling abort() terminated by a signal
exit() and _exit() #include <stdlib.h> void exit(int status); #include <unistd.h> void _exit(int status); These two functions terminate a program normally : _exit, which returns to the kernel immediately. exit, which performs certain cleanup processing and the returns to the kernel fclose() all open streams fflush() returns to kernel immediately
exit() and _exit() (cont..) Both the exit and _exit functions expect a single integer argument, which we call the exit status. Most UNIX shells provide a way to examine the exit status of a program, if A) either of these functions is called without an exit status B) main does a return without a return value C) main “falls off the end”(an implicit return), the exit status of the process is undefined. This means that the classic example #include<stdio.h> main() { printf(“Hello World !”); } Is incomplete, since the main function falls off the end, returning to the c start-up routine, but without returning a value(the exit status). Adding either return(0); or exit(0); Provides an exit status 0 to the process that executed this program(often a shell). int main(void)
atexit(): Exit Handler SYNOPSIS #include <stdlib.h> int atexit( void (*function)(void)); DESCRIPTION The atexit() function registers the given function to be called at normal process termination, either via exit(0) or via return from the program's main(). Functions so registered are called in the reverse order of their registration; no arguments are passed. The same function may be registered multiple times: it is called once for each registration. Can register up to 32 functions.
atexit(): Exit Handler (Cont..) RETURN VALUE The atexit() function returns the value 0 if successful; otherwise it returns a non-zero value. With ANSI C and POSIX.1, exit first calls the exit handlers and then fcloses all open streams.
Now lets see How a C program is started and how it terminates
When a C program is started by the kernel (by one of the exec functions) , a special start-up routine is called before the main function is called. The executable program files specifies this start-up routine as the starting address for the program-that is when it is invoked by the C compiler, usually CC. This start-up routine takes values from the kernel(the command-line arguments and the environment) and sets things up so that the main function is called.
Program 7.1: Exit Handlers #include "ourhdr.h" static void my_exit1(void), my_exit2(void); int main(void) { if (atexit(my_exit2) != 0) err_sys("can't register my_exit2"); if (atexit(my_exit1) != 0) err_sys("can't register my_exit1"); if (atexit(my_exit1) != 0) err_sys("can't register my_exit1"); printf("main is done\n"); return(0); }
Environment List Each program is also passed an environment List. Like the argument list, the environment list is an array of character pointers. With each pointer containing the address of null terminated C string. The Address of the array of pointers is contained in the global variables environ. extern char **environ;
Environment List (Cont…) For example, if the environment list consisted of five strings it could look like this.
Memory Layout of C Program Text segment: Machine instructions executed by CPU. (read-only, sharable) Initialized data segment: e.g. int maxcount = 99; (initialized!) Uninitialized data segment: This segment is often called the “bss” segment. (bss: block started by symbol)e.g. long sum[1000]; Stack: automatic variables, function calling information, context-switch information, (recursive functions) Heap: dynamic memory allocation
size $ size /bin/cc /bin/sh text data bss dec hex 81920 16384 664 98968 18298 /bin/cc 90112 16384 0 106496 1a000 /bin/sh The fourth and fifth columns are the total of the sizes in decimal and hexadecimal
Shared Libraries Shared libraries remove the Common library routines from executable files. Maintain the Single copy of library routines in the memory that all processes reference. This reduces the size of each executable file but many add some run-time overhead, either when the program is first executed, or the first time each shared library function is called. Another advantage of shared libraries is that library functions can be replaced with new versions without having to re-link edit every program that uses the library.
Memory Allocation There are three functions specified by ANSI C for memory allocation. malloc() - allocates a specified number of bytes of memory. The initial value of the memory is undetermined. calloc() – allocates apace for a specified number of objects of a specified size. The space is initialized to all 0 bits. realloc() – Changes the size of a previously allocated area( increases or decreases). Initial value of any additional space is indeterminate. All three return pointer suitably aligned for any kind of data.