"Hello Sir, I was going through setjmp. I came across your nice article http://web.eecs.utk.edu/~jplank/plank/classes/cs360/360/notes/Setjmp/lecture.html. I tried some things with setjmp. But with the attached program (compiled on GCC 4.4.1 in Ubuntu 9.10), I found that the code crashes due to SIGSEGV. Could you please help me in understanding why it results in a segmentation fault? Am I doing something that I am not supposed to do? Thanks in advance for your help. Thanks and regards, Waluigi....."
While you do don't get paid to help people like Waluigi, you feel it is rude to ignore him, so you look at his program:
#include <stdio.h> #include <stdlib.h> #include <setjmp.h> jmp_buf buf; void g(int n); void h(int n); int n = 6; static int counter = 3; void f(void) { int x[n]; // valid: f is not terminated printf("Entered function = f\n"); g(n); //this gets it core dumping printf("Value returned by setjmp = %d\n",setjmp(buf)); g(n); printf("Exiting function = f\n"); } void g(int n) { int a[n]; // a may remain allocated printf("Entered function = g\n"); h(n); printf("Exiting function = g\n"); } void h(int n) { int b[n]; // b may remain allocated printf("Entered function = h\n"); if(--counter > 0) longjmp(buf, 4); // might cause memory loss printf("Exiting function = h\n"); } int main (int argc, char *argv[]) { f(); return EXIT_SUCCESS; } |
We won't recount the ways in which Waluigi's program makes you feel ill. After taking an aspirin, you scan the program and figure out why it segfaults. Explain to me why it has a segmentation violation and what the output will be before the segfault. Be precise about why it segfaults.
----------------------------------------------------------------------------------------------------------------
int cproc(int **x) { int y; y = b(x[15], 7); return y+3; } |
void b() { int *x; int i; x = (int *) malloc(sizeof(int) * 10); printf("0x%x\n", x); for (i = 0; i < 10; i++) { *x = i*40; x++; } free(x); } |
#include <stdio.h> #include <stdlib.h> #include <pthread.h> typedef struct { int id; int n; pthread_t tid; /* Your Code Here: A */ } Thread_Info; void *thread(void *arg) { Thread_Info *ti; ti = (Thread_Info *) arg; do_random_stuff(ti); /* Your Code Here: B */ do_more_random_stuff(ti); } main(int argc, char **argv) { Thread_Info *ti; int i; int n; /* Your Code Here: C */ n = atoi(argv[1]); for (i = 0; i < n; i++) { ti = (Thread_Info *) malloc(sizeof(Thread_Info)); ti->id = i; ti->n = n; /* Your Code Here: D */ pthread_create(&(ti->tid), NULL, thread, (void *) ti); } pthread_exit(NULL); } |
You are only allowed to use the following thread calls:
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); int pthread_detach(pthread_t thread); int pthread_join(pthread_t thread, void **value_ptr); int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); void pthread_exit(void *value_ptr); |
#include <fcntl.h> #include <stdio.h> #include <stdlib.h> main() { int fd1, fd2, fd3, fd4, i; char buf[10]; fd1 = open("f1.txt", O_RDONLY); fd2 = open("f2.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666); fd3 = open("f3.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666); fd4 = dup(0); dup2(fd1, 0); dup2(fd2, 1); i = read(fd1, buf, 9); if (i < 0) exit(0); write(fd2, buf, i); i = read(0, buf, 9); if (i < 0) exit(0); write(1, buf, i); i = read(fd4, buf, 9); if (i < 0) exit(0); write(fd3, buf, i); dup2(fd4, 0); close(fd1); close(fd2); close(fd3); close(fd4); scanf("%d", &i); printf("%d\n", i); exit(0); } |
I compile the program into an executable called a.out, and I have the following input files:
f1.txt |
f4.txt |
Tell me the output of the following three commands (executed in this order). If there is a segmentation violation, or the program aborts due to an error, include that in your output.
UNIX> ./a.out < f4.txt UNIX> cat f2.txt UNIX> cat f3.txt