04 Process Environment
04 Process Environment
Chris Kauffman
Last Updated:
Mon Feb 8 03:54:59 PM CST 2021
1
Logistics
Reading Labs/HWs
▶ Stevens/Rago, Ch 7-8 ▶ Lab02 / HW02 due Mon
(Procs / Env) ▶ Lab03 on Mon, realloc()
▶ Stevens/Rago Ch 3, 4, 5, 6 function,
(I/O + Files) ▶ HW03: on Mon WNOHANG
and parents
Goals Today
▶ Process Lifecycle Project 1
▶ Killing programs ▶ Up now
▶ Process memory layout ▶ Due Mon 2/22 11:59pm
▶ Command Line Args ▶ Partners allowed
▶ Environment Variables ▶ Will create Piazza post for
▶ Start I/O discussion finding partners
2
Process: A “Running” Program
3
Process Life Cycle
5
Handy Commands
▶ top: interactively observe top running processes, usually
sorted by CPU usage
▶ ps: snapshot of running processes filtered on various criteria
▶ watch: repeatedly run a command showing its output on the
screen
Interactively observe all processes sorting by top CPU usage
> top
press q to quit
Watch processes with command name yes refreshing every 0.1
seconds showing u-ser relevant information on the processes
6
Terminal: Foreground/Background Processes
▶ Type a program into the terminal, press enter
▶ Stars a process in the foreground of the terminal
▶ Input from user typing, output to terminal screen
▶ Jobs can be run in the background as well
▶ Usually input must come from somewhere aside from user
typing, output should go into a file or it will pollute the
terminal
Key/Cmd Effect
Ctrl-z Stop/Suspend foreground process, gets prompt back
Ctrl-c Terminate foreground process (usually)
ls & Run program in background, gets prompt immediately
bg %2 Moves stopped Job 2 to background and continues it
fg %4 Moves background Job 4 to foreground
jobs List jobs under the control of the terminal
kill %3 End job 3 nicely
kill -9 %3 End job 3 unequivocally
7
Exercise: Basic Job Control
Give a sequence of commands / keystrokes to…
Misbehaving
▶ Compile no_interruptions.c to a program named
invincible
▶ Run invincible
▶ Try to end the process by sending it the interrupt signal
▶ In a separate terminal, end the invicible program
Keystrokes to Remember
Ctrl-c Send the interrupt signal, kills most processes
Ctrl-z Send the stop signal, puts process to sleep
9
States of a Living Process
▶ Note inclusion of
Kernel/OS here
▶ Interrupt and Sys
Calls start running
code in the operating
system
▶ Interrupt/Signal can
come from software
or hardware
▶ Context switch
starts running another
process, only happens
when one process is
Source: Design of the Unix Operating System by Maurice Bach
safely tucked in and
put to sleep
10
Recall: Program Memory
11
Answers: Program Memory
▶ What are the 4 memory areas to a C program we’ve discussed
OR that you know from previous courses?
1. Stack: automatic, push/pop with function calls
2. Heap: malloc() and free()
3. Global: variables outside functions, static vars
4. Text: Assembly instructions
▶ Give an example of how one creates variables/values in each
area of memory
1 #include <stdlib.h>
2 int glob1 = 2; // global var
3 int func(int *a){ // param stack var
4 int b = 2 * (*a); // local stack var
5 return b; // de-allocate locals in func()
6 }
7 int main(){ // main entry point
8 int x = 5; // local stack var
9 int c = func(&x); // local stack var
10 int *p = malloc(sizeof(int)); // local stack var that points into heap
11 *p = 10; // modify heap memory
12 glob1 = func(p); // allocate func() locals and run code
13 free(p); // deallocate heap mem pointed to p
14 return 0; // deallocate locals in main()
15 }
16 // all executable code is in the .text memory area as assmebly instructions
12
More Detailed Process Memory
13
Yet more detailed view (Link)
A detailed picture of the virtual memory image, by Wolf Holzman
Memory Layout (Virtual address space of a C process)
System High memory Stack illustrated after the call
func(72,73) called from main(),
assuming func defined by:
env func(int x, int y) {
STACK
argv
argc int a;
mfp − frame pointer (for main) int b[3];
auto variables for
main() /* no other auto variables */
auto variables for Assumes int = long = char * of
func()
stack pointer size 4 and assumes stack at high
(grows downward if func() address and descending down.
calls another function)
available for Expanded view of the stack
stack growth
Stack
global variables uninitialized data (bss) are referenced via offsets from the
frame pointer.
printf.o (lib*.a) (not usual case) is stored in a register. The stack pointer
file.o is move to the y location, the code
func(72,73) ra (return address) is jumped to the return address (ra),
main.o and the frame pointer is set to mfp
crt0.o (startup routine) (the stored value of the caller’s frame
Low memory pointer). The caller moves the return
value to the right place.
14
Unix Processes In Memory
Solutions
▶ Don’t program in C
▶ Use a tool to help identify and fix problems
▶ Valgrind → FREE for Linux Programs
16
Code for overflow.c
1 // overflow.c: program traverses memory that it really ought not to by
2 // walking off the end of an array into parts unknown.
3
4 #include <stdio.h>
5 int main(int argc, char *argv[]){
6 char a[3] = {'A','B','C'};
7 int i = 0;
8 while(1){
9 printf("%c",a[i]);
10 i++;
11 if(i%40 == 0){
12 printf("\n");
13 }
14 }
15 return 0;
16 }
17
18 // ## COMPILE AND RUN
19 // > gcc overflow.c
20 // > ./a.out
21 // ABC..^@....E.....*V^@^@ ...^?^@^@X.^?^@^@^@^@^@^@.
22 // ^@^@^@9..*V^@^@.....^?^@^@^@^@^@^@^@^@^@^@..K..|..
23 // V^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^
24 // ......M.....
17
Valgrind: Memory Tool on Linux and Mac
▶ Valgrind catches most memory
errors
▶ Use of uninitialized memory
▶ Reading/writing memory after it
has been free’d
▶ Reading/writing off the end of
malloc’d blocks > gcc -g badmemory.c
▶ Memory leaks > ./a.out
-714833203
▶ Source line of problem happened 0
1
(but not cause) 4
9
▶ Super easy to use, installed on lab 16
machines 0
1
▶ Slows execution of program way ...
5
down 6
▶ Usually install on Linux via 7
8
> sudo apt install valgrind Segmentation fault (core dumped)
# what now??
18
Valgrind on Common Problems in badmemory.c
> valgrind ./a.out
==2913308== Memcheck, a memory error detector
==2913308== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2913308== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==2913308== Command: ./a.out
==2913308==
==2913308== Conditional jump or move depends on uninitialised value(s)
==2913308== at 0x109189: main (badmemory.c:6)
==2913308==
0
1
4
9
==2913308== Invalid write of size 4
==2913308== at 0x1091D2: main (badmemory.c:11)
==2913308== Address 0x4a43050 is 0 bytes after a block of size 16 alloc'd
==2913308== at 0x483877F: malloc (vg_replace_malloc.c:309)
==2913308== by 0x1091AA: main (badmemory.c:9)
...
8
==2913308== Invalid read of size 4
==2913308== at 0x10924E: main (badmemory.c:20)
==2913308== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==2913308== Process terminating with default action of signal 11 (SIGSEGV):
==2913308== dumping core
19
Debuggers
20
Communicating Information to Programs
21
Exercise: Command Line Arguments
int main(int argc, char *argv[])
2-arg version of main() will be set up to have number of
arguments and array of strings in it by whatever started it
Print Args
Write a quick C program which prints ALL of its argv elements as
strings. Print a special message if an arg is string --verbose
22
Answers: Command Line Arguments
File: 04-process-environment-code/print_args.c
1 // Print all the arguments in the argv array. Prints a special message
2 // if option is --verbose.
3
4 #include <stdio.h>
5 #include <string.h>
6
7 int main(int argc, char *argv[]){
8 printf("%d args received\n",argc);
9 for(int i=0; i<argc; i++){
10 printf("%d: %s\n",i,argv[i]);
11 if( strcmp(argv[i],"--verbose") == 0){
12 printf("Turning on VERBOSE output\n");
13 }
14 }
15 return 0;
16 }
23
Environment Variables
24
C Programs and Environment Vars
26
Exercise: Manipulate Environment Vars
Note the use of export to ensure child
Write a short C program which processes see the environment variables
behaves as indicated in the demo
> unset ROCK
▶ Prints ROCK and VOLUME > unset VOLUME
environment variables > gcc environment_vars.c
> a.out
▶ If ROCK is set to anything, ROCK not set
change VOLUME to “11” VOLUME is not set
> export VOLUME=7
> a.out
Use these functions ROCK not set
VOLUME is 7
char *getenv(const char *name); > export ROCK=yes
// NULL if name not sot > a.out
// otherwise pointer to value ROCK is yes
Turning VOLUME to 11
int setenv(const char *name, VOLUME is 11
const char *value, > echo $VOLUME
int rewrite); 7
// Change name value pair,
// if rewrite is 1, Note also that the program does not
// overwrite previous definitions change the shell’s values for ROCK: no child
can change a parent’s values (or mind)
27
Answers: Manipulate Environment Vars
See 04-process-environment-code/environment_vars.c
1 // environment_vars.c: solution to in-class exercise showing how to
2 // check and set environment variables via the standard getenv() and
3 // setenv() functions.
4 #include <stdlib.h>
5 #include <stdio.h>
6
7 int main(int argc, char *argv[]){
8
9 char *rock = getenv("ROCK");
10 if(rock == NULL){
11 printf("ROCK not set\n");
12 }
13 else{
14 printf("ROCK is %s\n",rock);
15 printf("Turning VOLUME to 11\n");
16 int fail = setenv("VOLUME","11",1);
17 if(fail){
18 printf("Couldn't change VOLUME\n");
19 }
20 }
21 char *volume = getenv("VOLUME");
22 if(volume == NULL){
23 volume = "not set";
24 }
25 printf("VOLUME is %s\n",volume);
26 return 0;
27 }
28