Lab Exercise: User-Level Thread Management in Operating System Kernels, Lab Reports of Operating Systems

A lab exercise for students in csce 351: operating system kernels course. The objective of the lab is to familiarize students with sigsetjmp and siglongjmp functions, debugging process with gdb, and timer signal in linux. Students will also lay the groundwork for programming assignment 1.

Typology: Lab Reports

Pre 2010

Uploaded on 08/30/2009

koofers-user-fz7
koofers-user-fz7 🇺🇸

10 documents

1 / 7

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
1
Name:____________________________________ SID: _______________________
CSCE 351: Operating System Kernels
Lab 1 – User-Level Thread Management
Basic Setup:
Accessibility to CSE
Copy jumplab.tar from ~ylu/share/csce351/ directory
Objectives:
The objectives of this lab are as follows:
Familiarize students with siglongjmp and sigsetjmp.
Expose students to the basic debugging process with GDB.
Expose students to the timer signal in Linux
Lay ground work for programming assignment 1
Estimated Lab Time: 75 minutes
Introduction
The objective of this exercise is to familiarize students with two standard C library
functions sigsetjmp and siglongjmp. Function sigsetjmp can be used to save the context of
the processor (e.g. registers) and stack environment into a buffer. This context can then
be retrieved using siglongjmp. The first time that sigsetjmp is called, it will return 0.
However, if it is returning from siglongjmp, it would return non-zero value. For more
information about these functions, check the UNIX/Linux man page.
Activity 1: Introduction to sigsetjmp and siglongjmp
For this activity, you will need to log-in to crow.unl.edu. Once log-in, obtain the program
from /home/fac/ylu/share/csce351/jumplab.zip. You can copy this file directly to your
directory. Once in your directory, unzip the file and you should have a folder called jumplab
in your directory. In jumplab directory, we will examine program jump.c (listed below)
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <string.h>
pf3
pf4
pf5

Partial preview of the text

Download Lab Exercise: User-Level Thread Management in Operating System Kernels and more Lab Reports Operating Systems in PDF only on Docsity!

Name:____________________________________ SID: _______________________

CSCE 351: Operating System Kernels

Lab 1 – User-Level Thread Management

Basic Setup:

  • Accessibility to CSE
  • Copy jumplab.tar from ~ylu/share/csce351/ directory

Objectives:

The objectives of this lab are as follows:

  • Familiarize students with siglongjmp and sigsetjmp.
  • Expose students to the basic debugging process with GDB.
  • Expose students to the timer signal in Linux
  • Lay ground work for programming assignment 1

Estimated Lab Time: 75 minutes

Introduction

The objective of this exercise is to familiarize students with two standard C library

functions sigsetjmp and siglongjmp. Function sigsetjmp can be used to save the context of

the processor (e.g. registers) and stack environment into a buffer. This context can then

be retrieved using siglongjmp. The first time that sigsetjmp is called, it will return 0.

However, if it is returning from siglongjmp , it would return non-zero value. For more

information about these functions, check the UNIX/Linux man page.

Activity 1: Introduction to sigsetjmp and siglongjmp

For this activity, you will need to log-in to crow.unl.edu. Once log-in, obtain the program

from /home/fac/ylu/share/csce351/jumplab.zip. You can copy this file directly to your

directory. Once in your directory, unzip the file and you should have a folder called jumplab

in your directory. In jumplab directory, we will examine program jump.c (listed below)

#include <stdlib.h>

#include <stdio.h> #include <signal.h> #include <setjmp.h> #include <string.h>

int main(void) { sigjmp_buf buf_ptr; int retval; sigset_t sigmask; int testval = 100; char message[] = "Original Message"; if (sigsetjmp(buf_ptr,1) == 0) { fprintf (stderr,"1. message = %s, testval = %d\n", message, testval); strcpy (message, "New Message"); testval = 1000; fprintf (stderr,"2. message = %s, testval = %d\n", message, testval); } else { fprintf (stderr,"3. message = %s, testval = %d\n", message, testval); strcpy (message, "Newest Message"); testval = 10000; fprintf (stderr,"4. message = %s, testval = %d\n", message, testval); return; } siglongjmp(buf_ptr, 1); }

By inspecting the code, what do you think will be the output of this program?

Don’t worry about the correctness of your answer to the question above. If you are not

sure, just provide your best guess as the answer.

Next, compile this program (using gcc jump.c – o jump ) and run this program (using

./jump ). Is the output similar to your answer above? Also specify the rationales for your

provided answer.

Examine jump2.c in your jumplab directory. The program is also listed below:

#include <stdlib.h> #include <stdio.h> #include <signal.h> #include <setjmp.h> #include <string.h>

void proc1(char*); sigjmp_buf buf_ptr1;

int main(void) { int retval; int count = 0; sigset_t sigmask; char message[] = "Original Message"; sigsetjmp(buf_ptr1,1); fprintf (stderr,"1. message = %s\n", message); if (count >= 4) return; count++; proc1(message); } void proc1(char* message) { strcpy (message, "New Message"); siglongjmp(buf_ptr1, 1); }

The differences between this program and the previous program are as follows:

1. buf_ptr1 is a global variable which means that it is visible across function calls.

2. siglongjmp is called from a function outside of main.

3. we do not care about the return value of sigsetjmp.

Using GDB, monitor the execution of this program. Again pay special attention to EIP

and ESP registers.

Based on your observation of this program ( jump2.c ), do you think that the term “stack

environment” include the entire stack space? In other words, is the entire stack saved

when sigsetjmp is called?

What do you think the term “stack environment” include?

Activity 2: Creating user’s level threads

You have already seen that sigsetjmp can be used to create an execution entry point. That

is when sigsetjmp is called, the processor’s context and stack environment are saved and

siglongjmp can be used to restart a program at this exact same point in execution. Our

next task is to create necessary components that would allow multiple execution contexts.

As stated in the lecture, each thread has its own text section and stack space. Executed

code can be the same or different among all threads.

Inside jumplab directory, examine and execute jump3.c. From the execution, it should be

apparent that this program is not correct. Based on your experience with sigsetjmp and

siglongjmp, explain why this program stays in an infinite loop?

There are two functions that have been created in this program, insert () and delete ().

These two functions operate on a global variable i. We have already invoked two

sigsetjmp at the beginning of the program. These two sigsetjmp calls will serve as two

different execution contexts. However, these two contexts execute exactly the same code

and also share the same stack space. Our goal is to create two different stack spaces for

these two execution contexts and then map one context to insert() and another to delete().

Step 1: you will need to create two stack spaces for each of your execution context. You

can use malloc or calloc routine to do this. I have already declared the variable for your

stacks (stack1 and stack2). Let’s set the initial stack size to 4096 bytes.

Step 2: Accessing to the data in stored in a variable of type sigjmp_buf can be easily

done by indexing into the buffer array. For example, to access the value of the stack

pointer stored in buf1 (from our example), you would use:

buf1[1]

Similarly, to overwrite the value of program counter (PC) stored in buf1, you would use:

buf1[2]

/* initialize timer to send signal every 300 ms */ clocktimer.it_value.tv_sec = 0; clocktimer.it_value.tv_usec = INTERVAL; clocktimer.it_interval.tv_sec = 0; clocktimer.it_interval.tv_usec = INTERVAL; setitimer (ITIMER_REAL, &clocktimer, &oldclocktimer); sigset (SIGALRM, signal_processor); producer(); }

void signal_processor( int signal ) { printf ("get a signal\n"); } void producer() { int i; while(1){ for (i = 0; i < 1000000; i++); printf ("Producer\n"); } }

Step 1: Compile timer.c (available in jumplab directory).

Step 2: Execute the binary of timer.c.

Step 3: Examine the execution and the output. Explain what is the role of function

signal_processor.

End of In-Lab Exercise: submit the hardcopy of your lab report (i.e. this document) to

the instructor at the beginning of your next lecture.