• 沒有找到結果。

Final for SP Spring 2011

N/A
N/A
Protected

Academic year: 2022

Share "Final for SP Spring 2011"

Copied!
26
0
0

加載中.... (立即查看全文)

全文

(1)

Copyright©Chi-Sheng Shih

Final for SP Spring 2011

Copyright©Chi-Sheng Shih

Final Exam

Date: June 22nd, 2011 Time: 9:10AM ~ 12:00PM Location: Rm. 102 and 104

Coverage: Ch (6), 7, 8, 10, 15.1~15.5, (15.6~7)

(2)

Copyright©Chi-Sheng Shih

Chapter 6

The purpose of having passwd and shadow The returned records are static variables, which impose certain constraint of using the related functions.

How to know the users in the systems?

Process time vs. Calendar time

Copyright©Chi-Sheng Shih

Chapter 7

(3)

How a C program is started and terminated?

C start-up routine

kernel main

function user functions

exit function

exit handler

exit handler

standard I/O cleanup

exec

user process

callreturn call

return

exit

(doe s not

return)

exit

(does not return)

exit

(doe s not

return)

call

return call return call return _exit

or

_Exit _exit or _Exit

_exit or _Exit

Typical Memory Arrangement

Stack

Heap

un-initialized data (bss)

initialized data text

Initialized to 0 by exec.

Read from program file by exec.

command-line arguments and environment variables.

High address

Low address

(4)

Stack

Heap

un-initialized data (bss)

initialized data

text

Frame for main() Line 9

Frame for first_function() Space for an int Space for an char Space for an void * Line 22

Frame for second_function() Space for an int

Line 29

1. #include <stdio.h>

2. void first_function(void);

3. void second_function(int);

4.5.

6. int main(void) 7. {

8. printf("hello world\n");

9. first_function();

10. printf("goodbye goodbye\n");

11.12. return 0;

13. } 14.15.

16. void first_function(void) 17. {

18. int imidate = 3;

19. char broiled = 'c';

20. void *where_prohibited = NULL;

21.22. second_function(imidate);

23. imidate = 10;

24. } 25.26.

27. void second_function(int a) 28. {

29. int b = a;

30. }

Shared Library

Why a shared library?

Remove common library routines from executable files.

Have an easy way for upgrading

Problems

More overheads: dynamic linking

Gcc:

Searches for shared libraries first.

Static linking can be forced with the -static option to gcc to avoid the use of shared libraries.

Supported by many Unix systems

(5)

Side effect for double free

Following malloc() may return the same address twice and trigger a segmentation fault.

B->fw or the first 4 bytes of B will be set to the address of A

When B is the address of a function pointer and B is evaluated to retrieve the stored function pointer, A will be returned.

Consequently, it may cause memory (buffer/heap) overflow attack.

setjmp and longjmp

#include <setjmp.h>

int setjmp(jmp_buf env);

Return 0 if called directly; otherwise, it could return a value val from longjmp().

env tends to be a global variable.

int longjmp(jmp_buf env, int val);

longjmp() unwinds the stack and affect some variables.

Program 7.4 – Page 198

setjmp and longjmp

(6)

Automatic, Register, and Volatile Variables

The compilation system tries to reduce code size and execution time on all machines, by optimizing code.

Registers in processors can be used to store variable values.

A register variable is stored in register to reduce the access time.

A volatile variable is ALWAYS read from memory.

A variable should be declared volatile whenever its value can be changed by something beyond the control of the program in which it appears, such as

a concurrently executing thread,

a variable can be modified by ISR, etc.

setjmp and longjmp

• Automatic, Register, and Volatile Variables

Compiler optimization

Register variables could be in memory.

Values are often indeterminate

Normally no roll back on automatic and register variables

Shown in Program 7.5 later

Global and static variables are left alone when longjmp is executed.

Portability Issues!

(7)

setjmp and longjmp

[cshih@oris environ]$ ./testjmp in f1():

globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99 after longjmp:

globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99 [cshih@oris environ]$ ./testjmp.opt

in f1():

globval = 95, autoval = 96, regival = 97, volaval = 98, statval = 99 after longjmp:

globval = 95, autoval = 2, regival = 3, volaval = 98, statval = 99

Program 7.5 – Page 200

Effects of longjmp

Variables stored in memory have their values unchanged – no optimization…

Copyright©Chi-Sheng Shih

Chapter 8

(8)

Multi-processes in modern systems

Image that you are now a system architect to design a new multi-process systems.

Q1: How does the system create a new process and terminate a process?

Q2: What processes you need when the system starts?

Q3: Should you impose a communist or democratic system on your system?

Memory Management

Virtual Memory – Demand paging

File System

Swap Space Run

Swap-Out/In

Logical Memory

Memory Map (Page Table)

Physical Memory

CPU

(9)

fork

#include <sys/types.h>

#include <unistd.h>

pid_t fork(void);

The only way beside the bootstrap process to create a new process.

Call once but return twice

0 for the child process (getppid) Child pid for the parent (1:n)

Copies of almost everything but no sharing of memory, except text

Copy-on-write (fork() – exec())

Program 8.1 – Page 212

fork

fork(), race conditions on shared files, write vs standard I/

O functions

The order of execution is in-determinate.

File sharing

Sharing of file offsets (including stdin, stdout, stderr)

Tables of Opened Files (per process)

System Open File Table

In-core i-node list

(10)

Write vs. Standard IO

[cshih@oris proc]$ ./fork1 a write to stdout

before fork

pid = 17194, glob = 7, var = 89 pid = 17193, glob = 6, var = 88

[cshih@oris proc]$ ./fork1 > temp.out [cshih@oris proc]$ cat temp.out

a write to stdout before fork

pid = 17188, glob = 7, var = 89 before fork

pid = 17187, glob = 6, var = 88

Data in output buffer are copied to child process.

Forked processes and their properties

Normal cases for handling file descriptors after fork():

The parent waits for the child to complete.

The parent and child each go their own way (e.g., network servers).

Inherited properties:

Real/effective [ug]id, supplementary gid, process group ID, session ID, controlling terminal, set[ug]id flag, current working dir, root dir, file-mode creation mask, signal mask & dispositions, FD_CLOEXEC flags, environment, attached shared memory

segments, resource limits (exec)

Differences on properties:

Returned value from fork, process ID, parent pid, tms_[us]time, tms_c[us]time, file locks, pending alarms, pending signals

(11)

vfork

vfork() is as the same as fork() except

The child runs in the address space of its parent.

The parent waits until the child calls exit or exec.

Child process always executes first.

Program 8.2 – Page 217

vfork,

_exit vs exit (flushing/closing of stdout)

exit() may close the file descriptors, causing printf() to fail.

A possibility of deadlock if the child waits for the parent to do something before calling exec().

wait & waitpid

#include <sys/types.h>

#include <sys/wait.h>

pid_t wait(int *statloc);

pid_t waitpid(pid_t pid, int *statloc, int op);

wait will block until one child terminates or an error could be returned.

waitpid could wait for a specific one and has an option not to be blocked.

SIGCHLD from the kernel if a child terminates

Default action is ignoring.

(12)

main() { ...

wait();

wait();

...

return 0;

}

Parent process

Parent process is suspended.

main() { ...

return 0;

}

Child process

A signal, SIGCHILD, to wake up the parent

process.

Discussion

wait() and waitpid() are called by the parent process to retrieve the termination status of its child process.

When a parent terminates before its child process terminated?

What are the impacts to the system?

Let it be? or ask someone to adopt it?

When a child process terminates before its parent process waits for its termination status?

What are the impacts to the system?

Let it be? or keep the address space until the parent needs it?

(13)

Discussion: why do we need zombie?

A parent process can end up with two different children that share the same PID.

A parent process can end up trying to wait for the return code of another process’s child.

The kernel won’t be able to correctly track which return code goes with which process (unless it uses additional, complex logic.)

Trouble for Zombie

It is a good practice to wait for child and to have zombie processes.

However, when the system is creating a large number of background process, i.e., daemon process, we would like to fork a new child process but

not asking the parent process to wait for the child AND

not generating zombie process?

(14)

Race Conditions

Def: When multiple processes are trying to do something with shared data, the final outcome depends on the order in which the processes run.

Example: Program 8.5 – Page 225

Who is the parent of the 2nd child?

Program 8.6 – Page 229

Mixture of output by putc + setting of unbuffering for stdout

exec

#include <unistd.h>

int execlp(const char *filename, const char *arg0, … /*

(char *) 0 */);

int execvp(const char *filename, char *const argv[]);

With p, a filename is specified unless it contains ‘/’.

PATH=/bin:/usr/bin:.

/bin/sh is invoked with “filename” if the file is not a machine executable file.

Example usage: login, ARG_MAX (4096) Figure 8.14 – Page 209 (6 exec functions)

(15)

exec

Inherited from the calling process:

pid, ppid, real [ug]id, supplementary gid, proc gid, session id, controlling terminal, time left until alarm clock, current working dir, root dir, file mode creation mask, file locks, proc signal mask, pending signals, resource limits, tms_

[us]time, tms_cutime, tms_ustime

(Inherited properties for forked process.) FD_CLOEXEC flag

Requirements & Changes

Closing of open dir streams,

Effective user/group ID: depends on the set-user-ID bit

exec

In many Unix implementations, execve is a system call.

Program 8.8 – Page 235 Program 8.9 – Page 236

The prompt bet the printing of argv[0] and argv[1].

execvp execlp

execv execl

execve execle

build argv build argv build

argv

try each PATH prefix

use environ

(16)

Use of setuid/setgid

To allow other users to access certain file when conducting certain operations.

Access passwd/shadow when a user logs in You can find it, using ‘ls’ with ‘-l’ options

An executable file can be a setuid program by adding

‘u+s’ or ‘g+s’ permission.

Examples of setuid program: passwd, login, etc.

However, executing the setuid program for a long time could cause many security problems.

During the execution, the privilege should be removed and given back only when necessary.

Copyright©Chi-Sheng Shih

Chapter 10

(17)

Handling Fresh Signals

Hardware Exception!!

User

Process P1 Set the signal flag for the target process

Check bottom_half queue

Blocked signal?

Ignored signal?

Insert the signal to pending queue

No

No

Handle signal

Software condition: kill()

Checkup at clock tick

Clear the flag

ISR()

Time

User Space Kernel Space

Handling Signals by Signal Handler

User Process P1

Signal handler

Deliver Signal

cleanup

User Space Kernel Space

interrupt!!

User Process P2

(18)

Interrupted System Calls

Traditional Approach

“Slow” system calls could be interrupted -> errno = EINTR

“Slow” System Calls (not disk I/O):

Reads from or writes to files that can block the caller

forever (e.g., pipes, terminal devices, and network devices) Opens of files (e.g., terminal device) that block until some conditions occurs.

pause, wait, certain ioctl operations Some IPC functions

Reentrant Functions

When interrupts occur, a function could be called twice and causes problems.

(Program 10.5 – Page 307) Potential Problem:

In the signal handler, we can’t tell where the process was executing when the signal was caught!

Examples: malloc, getpwnam

Occurrence Time: Anytime, e.g., by timer…

(19)

Unreliable Signals

Unreliable Signals: Signals could get lost!

Why?

The action for a signal was reset to its default each time the signal occurred.

The process could only ignore signals, instead of turning off the signals when the process is busy.

int sig_int();

signal(SIGINT, sig_int);

sig_int() {

signal(SIGINT, sig_int);

… }

(20)

39 main(void) {

unsigned int unslept;

if (signal(SIGINT, sig_int) == SIG_ERR) err_sys("signal(SIGINT) error");

unslept = sleep2(5);

unsigned int

sleep2(unsigned int nsecs) {

if (signal(SIGALRM, sig_alrm) == SIG_ERR) return(nsecs);

if (setjmp(env_alrm) == 0) {

alarm(nsecs); /* start the timer */

pause();

static void

sig_alrm(int signo) {

// Do nothing }

SIGINT

static void sig_int(int signo) {

printf("\nsig_int starting\n");

for (i = 0; i < 300000; i++) for (j = 0; j < 4000; j++)

k += i * j;

SIGALRM

if (setjmp(env_alrm) == 0) {

alarm(nsecs); /* start the timer */

pause();

}

return(alarm(0));

}

i=20000

static void sig_int(int signo) {

printf("\nsig_int starting\n");

i=20001 Correct nested

signal handling

Signal Mask

Signal mask is a per process property.

Under certain circumstance, we may desire the process not to be interrupted.

For example, in the process for changing handlers, in the process for handling a delivered signal, etc.

It defines the set of signals for being blocked.

Blocked signal vs. Ignored signal:

An ignored signal will NOT be delivered to the receiving process.

A blocked signal will be queued until the receiving process is ready to process the signal or the signal is ignored.

40

(21)

sigaction

#include <signal.h>

int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);

sa_mask: sigemptyset(), etc.

Figure 10.16 – sa_flags No queuing of signals

Unlike signal(), signal handlers remain!

struct sigaction {

void (*sa_handler)();

sigset_t sa_mask;

int sa_flags;

};

(including the delivered signal)

41

Changes of signal mask for sigaction

42

mask

sigpromask (SIG_SETMASK, emptyset, NULL)

sigpromask (SIG_BLOCK,

set1, NULL)

sigaction(SIGINT, act, oact) act.sa_mask=set2

SIGINT End of SIGINT handler emptyset

set1 set2 + SIGINT

SIGINT is not in set2

(22)

sigsetjmp & siglongjmp

#include <setjmp.h>

int sigsetjmp(sigjmp_buf env, int savemask);

void siglongjmp(sigjmp_buf env, int val);

sigsetjmp() saves the current signal mask of the process in env if savemask !=0.

setjmp & longjmp save/restore the signal mask:

4.3+BSD and Mac OS X, but not SVR4, Linux 2.4, and Solaris 9.

43

main() signal() signal() pr_mask() sigsetjmp()

pause()

sig_usr1 pr_mask()

alarm() time() time() time()

sig_alrm pr_mask()

return()

SIGUSR1 delivered

SIGALARM delivered

Return from signal hander

pr_mask() siglongjmp() sigsetjmp()

pr_mask() exit()

SIGUSR1

SIGUSR1 SIGARM

SIGUSR1

44

(23)

Revisit Race Condition by non-atomic functions

Recall that, race condition between alarm() and pause() may block a process forever if there is no other signals.

Similar race condition may occur between sigprocmask() and pause(), which leads to missed signals.

45 sigset_t newmask, oldmask;

sigemptyset(&newmask);

sigaddset(&newmask, SIGINT);

/* block SIGINT and save current signal mask */

if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) err_sys("SIG_BLOCK error");

/* critical region of code */

/* reset signal mask, which unblocks SIGINT */

if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) err_sys("SIG_SETMASK error");

/* window is open */

pause(); /* wait for signal to occur */

/* continue processing */

A delivered signal could be

lost.

sigsuspend

#include <signal.h>

int sigsuspend(const sigset_t

*sigmask);

Set the signal mask to sigmsk and suspend until a signal is caught or until a signal occurs that terminates the process.

Return –1. errno = EINTR

The mask is restored when the function returns.

if (sigprocmask(…) < 0) err_sys(…);

pause();

CPU Scheduling could occur!

46

(24)

Changes of signal mask for sigaction

47

mask

sigpromask (SIG_BLOCK,

&newmask,

&oldmask)

SIGSUSPEND org. set

org. set + SIGINT

SIGUSR1

Critical Section

SIGUSR2 SIGUSR1 +

SIGUSR2

sigprocmask (SIG_SETMASK,

&oldmask, ..) return of

SIGSUSPEND

Copyright©Chi-Sheng Shih

Chapter 15

(25)

Pipes

Pipes have two limitations:

They are half-duplex.

They can be used between processes that have a common ancestor.

Stream pipes are duplex and named stream pipes can be used between processes not having the same ancestor.

pipe function

! #include <unistd.h>

! int pipe( int filedes[2] );

FIFOs

FIFOs – named pipes for (un-)related processes to exchange data.

A file type – st_mode (S_ISFIFO macro)

Data in a FIFO removed when the last referencing process terminates.

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);

mode and usr/grp ownership = those of a file Op’s: open, close, read, write, unlink, etc.

(26)

Message Queues

Message Queue or Queue

A linked list of messages stored within the kernel and with a queue ID

struct msqid_ds {

struct ipc_perm msg_perm;

ulong msg_qnum; /* # of msgs */

ulong msg_qbytes; /* max # of bytes */

pid_t msg_lspid; /* pid of the last msgsnd() */

pid_t msg_lrpid; /* pid of the last msgrcv() */

time_t msg_stime; /* the last msgsnd() time */

time_t msg_rtime; /* the last msgrcv() time */

time_t msg_ctime; /* last change time */

}

Msgs could be fetched based on their type field.

參考文獻

相關文件

The performance guarantees of real-time garbage collectors and the free-page replenishment mechanism are based on a constant α, i.e., a lower-bound on the number of free pages that

[r]

For any self-financing post-secondary education institutions registered under the Ordinance aspiring to become private universities, we shall maintain the current

Direct Access Attack 直接訪問攻擊. 詳細的攻擊手段描述請閱附件一 SQL

存放檔案的 inode 資訊, inode 一旦滿了也一樣會 無法儲存新檔案, inode 會告知檔案所使用的 data block 位置。. Q :如何知道那些 inode 和

Briefing of the home assignment (Designing a plan for e-assessment) Ø  Participants have to complete the assignment before attending Session 2 Ø  File name:

contributions to the nearby pixels and writes the final floating point image to a file on disk the final floating-point image to a file on disk. • Tone mapping operations can be

Put the current record with the “smaller” key field value in OutputFile if (that current record is the last record in its corresponding input file) :. Declare that input file to be