Action Items
Project Design and Progress reviews will start next week. The submission form for updates and scheduling is due by 11:59pm Sunday.
Segmentation Violations
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void (*signal(int signum, void (*sighandler)(int)))(int);
static int i;
void catch_segv(int sig) {
printf("Caught segv: %d\n", sig);
printf("i = %d\n", i);
}
int main(int argc, char **argv) {
char *s = (char *) malloc (1);
i = 0;
signal(SIGSEGV, catch_segv);
while (1) {
s[i] = 'a';
i++;
}
}
When does this code produce a Segmentation Violation?
#include <stdio.h>
#include <stdlib.h>
void big_stack() {
char BIG_DATA[8515*1024];
int i = 3; // need this to avoid optimizations...
}
int main(int argc, char **argv) {
big_stack();
}
Try uname -a
to determine if this code will SEGV or not on your machine.
Representing Tasks
struct task_struct {
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
void *stack;
atomic_t usage;
unsigned int flags; /* per process flags, defined below */
unsigned int ptrace;
... // 400 lines total
int prio, static_prio, normal_prio;
unsigned int rt_priority;
const struct sched_class *sched_class;
...
struct mm_struct *mm, *active_mm;
/* task state */
int exit_state;
int exit_code, exit_signal;
int pdeath_signal; /* The signal sent when the parent dies */
unsigned int jobctl; /* JOBCTL_*, siglock protected */
/* Used for emulating ABI behavior of previous Linux versions */
unsigned int personality;
...
pid_t pid;
pid_t tgid;
#ifdef CONFIG_CC_STACKPROTECTOR
/* Canary value for the -fstack-protector gcc feature */
unsigned long stack_canary;
#endif
/*
* pointers to (original) parent process, youngest child, younger sibling,
* older sibling, respectively. (p->father can be replaced with
* p->real_parent->pid)
*/
struct task_struct __rcu *real_parent; /* real parent process */
struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
/*
* children/sibling forms the list of my natural children
*/
struct list_head children; /* list of my children */
struct list_head sibling; /* linkage in my parent's children list */
struct task_struct *group_leader; /* threadgroup leader */
...
};
Why does the kernel need to know about GCC's -fstack-protector
feature?
...
#define MINIX_SUPER_MAGIC 0x137F /* minix v1 fs, 14 char names */
#define MINIX_SUPER_MAGIC2 0x138F /* minix v1 fs, 30 char names */
#define MINIX2_SUPER_MAGIC 0x2468 /* minix v2 fs, 14 char names */
#define MINIX2_SUPER_MAGIC2 0x2478 /* minix v2 fs, 30 char names */
#define MINIX3_SUPER_MAGIC 0x4d5a /* minix v3 fs, 60 char names */
...
#define STACK_END_MAGIC 0x57AC6E9D
...
How should the kernel flush the TLB?
static inline void __native_flush_tlb(void)
{
native_write_cr3(native_read_cr3());
}
Is Mark's answer correct? What unstated assumptions does it rely on?
For a more truthful account of how Mark did in his Operating Systems course, see Matt Welsh's How I almost killed Facebook.