tlpi - 6 process

26
TLPI - 6 Processes Shu-Yu Fu ([email protected])

Upload: shu-yu-fu

Post on 19-May-2015

565 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: TLPI - 6 Process

TLPI - 6ProcessesShu-Yu Fu ([email protected])

Page 2: TLPI - 6 Process

In This Chapter● the structure of a process● the attributes of a process

Page 3: TLPI - 6 Process

Processes and Programs● A process is an instance of an executing

program.● A program is a file containing a range of

information that describes how to construct a process at run time.○ Binary format identification (COFF, PE2, ELF)○ Machine-language instructions (text section)○ Program entry-point address (ld-script, ld --verbose)○ Data (data and rodata sections)○ Symbol and relocation tables (symbol relocation)○ Shared-library and dynamic-linking information○ Other information

Page 4: TLPI - 6 Process

Process ID and Parent Process ID#include <unistd.h>pid_t getpid(void);pid_t getppid(void);

Page 5: TLPI - 6 Process

Memory Layout of a Process● The text segment● The initialized data

segment (data)● The uninitialized

data segment (bss)● The stack● The heap

The top end of the heap is called the program break

Page 6: TLPI - 6 Process

Locations of program variables in process memory segments#include <stdio.h>

#include <stdlib.h>

/* Uninitialized data segment */

char globBuf[65536];

/* Initialized data segment */

int primes[] = {2, 3, 5, 7};

static int

square (int x) { /* Allocated in frame for square() */

int result; /* Allocated in frame for square() */

result = x * x;

return result; /* Return value passed via register) */

}

static void

doCalc (int val) { /* Allocated in frame for doCalc() */

printf ("The square of %d is %d\n", val, square (val));

if (val < 1000) {

int t; /* Allocated in frame for doCalc() */

t = val * val * val;

printf ("The cube of %d is %d\n", val, t);

}

}

int

main (int argc, char *argv[]) { /* Allocated in frame for main() */

static int key = 993; /* Initialized data segment */

static char mbuf[64]; /* Uninitialized data segment */

char *p; /* Allocated in frame for main() */

p = malloc (8); /* Points to memory in heap segment */

doCalc (key);

exit (EXIT_SUCCESS);

}

Page 7: TLPI - 6 Process

Virtual Memory Management● A virtual memory scheme splits the memory

used by each program into small, fixed-size units called pages.

● At any one time, only some of the pages of a program need to be resident in physical memory page frames; these pages form the so-called resident set.

Page 8: TLPI - 6 Process

Virtual Memory Management (cont.)● Copies of the unused pages of a program

are maintained in the swap area--a reserved area of disk space used to supplement the computer's RAM--and loaded into physical memory only as required.

● When a process reference a page that is not currently resident in physical memory, a page fault occurs.

● The kernel maintains a page table for each process.

Page 9: TLPI - 6 Process

Page Table

Page 10: TLPI - 6 Process

Virtual Memory Management (cont.)● The page table describes the location of

each page in the process's virtual address space.

● If a process tries to access an address for which there is no corresponding page-table entry, it receives a SIGSEGV signal.

● A process's range of valid virtual addresses can change over its lifetime.○ stack grows, brk(), sbrk(), malloc() family, shmat(),

shmdt(), mmap(), munmap()

Page 11: TLPI - 6 Process

Advantages● Processes are isolated from one another and from the

kernel.● Where appropriate, two or more processes can share

memory.● Page-table entries can be marked to indicate that the

contents of the corresponding page are readable, writable, executable, or some combination of these protections.

● Programmers don't need to be concerned with the physical layout of the program in RAM.

● Because only a part of a program needs to reside in memory, the program loads and runs faster.

Page 12: TLPI - 6 Process

The Stack and Stack Frames● A special-purpose register, the stack pointer,

tracks the current top of the stack.● Sometimes, the term user stack is used to

distinguish the stack we describe here from the kernel stack.

● Each (user) stack frame contains the following information:○ Function arguments and local variables○ Call linkage information

Page 13: TLPI - 6 Process

Command-Line Arguments

Page 14: TLPI - 6 Process

Command-Line Arguments (cont.)● The fact that argv[0] contains the name used

to invoke the program can be employed to perform a useful trick.

● The command-line arguments of any process can be read via the Linux-specific /proc/PID/cmdline file.

● The argv and environ arrays reside in a single continuous area of memory which has an upper limit on the total number of bytes that can be stored in this area.

Page 15: TLPI - 6 Process

Echoing Command-Line Arguments#include <stdlib.h>

int main (int argc, char * argv[]){ int j;

for (j = 0; j < argc; j++) printf ("argv[%d] = %s\n", j, argv[j]);

return (EXIT_SUCCESS);}

Page 16: TLPI - 6 Process

Environment List

Page 17: TLPI - 6 Process

Environment List (cont.)● Each process has an associated array of

strings called the environment list.● Each of these strings is a definition of the

form name=value.● When a new process is created, it inherits a

copy of its parent's environment.● The environment list of any process can be

examined via the Linux-specific /proc/PID/environ file.

Page 18: TLPI - 6 Process

Displaying the Process Environment#include <stdlib.h>

extern char **environ;

int main (int argc, char * argv[]){ char **ep;

for (ep = environ; *ep; ep++) puts (*ep);

return (EXIT_SUCCESS);}

Page 19: TLPI - 6 Process

Accessing the Environment From a Program

● #define _BSD_SOURCE● #include <stdlib.h>● int main(int argc, char *argv[], char *envp[]);● char * getenv(const char *name);● int putenv(char *string);● int setenv(const char *name, const char

*value, int overwrite);● int unsetenv(const char *name);● int clearenv(void);

Page 20: TLPI - 6 Process

Accessing the Environment From a Program (cont.)

● In some circumstances, the use of setenv() and clearenv() can lead to memory leaks in a proram.

● We noted above the setenv() allocates a memory buffer that is then made part of the environment.

● When we call clearenv(), it doesn't free this buffer.

Page 21: TLPI - 6 Process

Performing a Nonlocal Goto#include <setjmp.h>int setjmp(jmp_buf env);void longjmp(jmp_buf env, int val);

Page 22: TLPI - 6 Process

Demonstrate the Use of setjmp() and longjmp()#include <setjmp.h>

static jmp_buf env;

static void f2(void) {

longjmp(env, 2);

}

static void f1(int argc) {

if (argc == 1) longjmp(env, 1);

f2();

}

int main(int argc, char *argv[]) {

switch (setjmp(env)) {

case 0:

printf("Calling f2() after initial setjmp()\n");

f1(argc);

break;

case 1:

printf("We jumped back from f1()\n");

break;

case 2:

printf("We jumped back from f2()\n");

break;

}

exit(EXIT_SUCCESS);

}

$./longjmpCalling f1() after initial setjmp()

We jumped back from f1()

$./longjmp xCalling f1() after initial setjmp()

We jumped back from f2()

Page 23: TLPI - 6 Process

Restrictions on The Use of setjmp()● A call to setjmp() may appear only in the

following contexts:○ if, switch, or iteration statement○ A unary ! operator○ comparison (==, !=, <, and so on) with integer○ A free-standing function call

Page 24: TLPI - 6 Process

Abusing longjmp()1. Call a function x() that uses setjmp() to establish a jump

target in the global variable env.2. Return from function x().3. Call a function y() that does a longjmp() using env.4. This is a serious error. We can't do a

longjmp() into a function that has already returned.

5. In a multithreaded program, a similar abuse is to call longjmp() in a different thread from that in which setjmp() was called.

Page 25: TLPI - 6 Process

Problems with Optimizing Compilers#include <stdio.h>

#include <stdlib.h>

#include <setjmp.h>

static jmp_buf env;

static void doJump(int nvar, int rvar, int vvar)

{

printf("Inside doJump(): nvar=%d rvar=%d

vvar=%d\n", nvar, rvar, vvar);

longjmp(env, 1);

}

int main(int argc, char *argv[])

{

int nvar;

register int rvar;

volatile int vvar;

nvar = 111;

rvar = 222;

vvar = 333;

if (setjmp(env) == 0) {

nvar = 777;

rvar = 888;

vvar = 999;

doJump(nvar, rvar, vvar);

} else {

printf("After longjmp(): nvar=%d rvar=%d

vvar=%d\n", nvar, rvar, vvar);

}

exit(EXIT_SUCCESS);

}

$ cc -o setjmp_vars setjmp_vars.c$ ./setjmp_varsInside doJump(): nvar=777 rvar=888 vvar=999After longjmp(): nvar=777 rvar=888 vvar=999

$ cc -O =o setjmp_vars setjmp_vars.c$ ./setjmp_varsInside doJump(): nvar=777 rvar=888 vvar=999After longjmp(): nvar=111 rvar=222 vvar=999

Page 26: TLPI - 6 Process

Summary● Each proess has q unique process ID and maintains a record of its

parent's process ID.

● The virtual memory of a process is logically divided into a number of segments.

● The stack consists of a series of frames.

● The command-line arguments supplied when a program is invoked are made available via the argc and argv arguments to main().

● Each process receives a copy of its parent's environment list.

● The setjmp() and longjmp() functions provide a way to perform nonlocal goto from one function to another.○ Avoid setjmp() and longjmp() where possible