1    	/*****************************************************************************
2    	 *   Copyright (C) 2006-2009 by Michael Rieker, Jason Ansel, Kapil Arya, and *
3    	 *                                                            Gene Cooperman *
4    	 *   mrieker@nii.net, jansel@csail.mit.edu, kapil@ccs.neu.edu, and           *
5    	 *                                                          gene@ccs.neu.edu *
6    	 *                                                                           *
7    	 *   This file is part of the MTCP module of DMTCP (DMTCP:mtcp).             *
8    	 *                                                                           *
9    	 *  DMTCP:mtcp is free software: you can redistribute it and/or              *
10   	 *  modify it under the terms of the GNU Lesser General Public License as    *
11   	 *  published by the Free Software Foundation, either version 3 of the       *
12   	 *  License, or (at your option) any later version.                          *
13   	 *                                                                           *
14   	 *  DMTCP:dmtcp/src is distributed in the hope that it will be useful,       *
15   	 *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
16   	 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
17   	 *  GNU Lesser General Public License for more details.                      *
18   	 *                                                                           *
19   	 *  You should have received a copy of the GNU Lesser General Public         *
20   	 *  License along with DMTCP:dmtcp/src.  If not, see                         *
21   	 *  <http://www.gnu.org/licenses/>.                                          *
22   	 *****************************************************************************/
23   	
24   	#include "mtcp_ptrace.h"
25   	#include <pthread.h>
26   	#include <semaphore.h>
27   	#include <unistd.h>
28   	
29   	#ifdef PTRACE
30   	
31   	#include <stdio.h>
32   	#include <errno.h>
33   	#include <string.h>
34   	#include <stdlib.h>
35   	#include <sys/types.h>
36   	#include <sys/wait.h>
37   	#include <sched.h>
38   	#include <sys/user.h>
39   	#include <sys/syscall.h>
40   	
41   	#define GETTID() (int)syscall(SYS_gettid)
42   	
43   	int only_once = 0;
44   	
45   	const unsigned char DMTCP_SYS_sigreturn =  0x77;
46   	const unsigned char DMTCP_SYS_rt_sigreturn = 0xad;
47   	
48   	static const unsigned char linux_syscall[] = { 0xcd, 0x80 };
49   	
50   	static __thread int is_waitpid_local = 0;
51   	static __thread int is_ptrace_local = 0;
52   	static __thread pid_t saved_pid = -1;
53   	static __thread int saved_status = -1;
54   	static __thread int has_status_and_pid = 0;
55   	
56   	__thread pid_t setoptions_superior = -1;
57   	__thread int is_ptrace_setoptions = FALSE;
58   	
59   	static pthread_mutex_t ptrace_pairs_mutex = PTHREAD_MUTEX_INITIALIZER;
60   	
61   	struct ckpt_thread {
62   	  pid_t pid;
63   	  pid_t tid;
64   	};
65   	
66   	sem_t ptrace_read_pairs_sem;
67   	int init_ptrace_read_pairs_sem = 0;
68   	
69   	sem_t __sem;
70   	int init__sem = 0;
71   	
72   	char ptrace_shared_file[MAXPATHLEN];
73   	char ptrace_setoptions_file[MAXPATHLEN];
74   	char checkpoint_threads_file[MAXPATHLEN];
75   	
76   	int has_ptrace_file = 0;
77   	pid_t delete_ptrace_leader = -1;
78   	int has_setoptions_file = 0;
79   	pid_t delete_setoptions_leader = -1;
80   	int has_checkpoint_file = 0;
81   	pid_t delete_checkpoint_leader = -1;
82   	
83   	struct ptrace_tid_pairs ptrace_pairs[MAX_PTRACE_PAIRS_COUNT];
84   	int ptrace_pairs_count = 0;
85   	int init_ptrace_pairs = 0;
86   	
87   	/***************************************************************************/
88   	/* THIS CODE MUST BE CHANGED TO CHECK TO SEE IF THE USER CREATES EVEN MORE */
89   	/* THREADS.                                                                */
90   	/***************************************************************************/
91   	#define MAX_CKPT_THREADS 100
92   	static struct ckpt_thread ckpt_threads[MAX_CKPT_THREADS];
93   	static int ckpt_threads_count = 0;
94   	
95   	static void have_file(pid_t pid);
96   	
97   	static int is_checkpoint_thread (pid_t tid);
98   	
99   	static int ptrace_detach_ckpthread(pid_t tgid, pid_t tid, pid_t supid);
100  	
101  	static void sort_ptrace_pairs ();
102  	
103  	static void print_ptrace_pairs ();
104  	
105  	static void reset_ptrace_pairs_entry ( int i );
106  	
107  	void check_size_for_ptrace_file (const char *file) {
108  	  struct stat buf;
109  	  if (!stat (file, &buf)) {
110  	    mtcp_printf ("WARNING: %s has %d bytes.\n", file, buf.st_size);
111  	  } else {
112  	    if (errno != ENOENT) {
113  	      mtcp_printf ("WARNING: stat failed for %s with an error different than ENOENT.\n",
114  	                   ptrace_shared_file);
115  	    }
116  	  }
117  	}
118  	
119  	
120  	void init_thread_local()
121  	{
122  	  is_waitpid_local = 0; // no crash on pre-access
123  	  is_ptrace_local = 0; // no crash on pre-access
124  	  saved_pid = -1; // no crash on pre-access
125  	  saved_status = -1; // no crash on pre-access
126  	  has_status_and_pid = 0; // crash
127  	
128  	  setoptions_superior = -1;
129  	  is_ptrace_setoptions = FALSE;
130  	}
131  	
132  	
133  	/* FIXME:  BAD FUNCTION NAME:  readall(..., ..., count) would guarantee
134  	 * to read 'count' characters.  This reads zero or more characters
135  	 * but does EAGAIN/EINTR processing so that the caller doesn't need to do it.
136  	 * Maybe a name like:  read_no_error() ?
137  	 */
138  	ssize_t readall(int fd, void *buf, size_t count)
139  	{
140  	  int rc;
141  	  do
142  	    rc = read(fd, buf, count);
143  	  while (rc == -1 && (errno == EAGAIN  || errno == EINTR));
144  	  if (rc == -1) { /* if not harmless error */
145  	    mtcp_printf("readall: Internal error\n");
146  	    mtcp_abort();
147  	  }
148  	  return rc; /* else rc >= 0; success */
149  	}
150  	
151  	void delete_file (int file, int delete_leader, int has_file)
152  	{
153  	  if ((delete_leader == GETTID()) && has_file) {
154  	    switch (file) {
155  	      case 0: {
156  	        if (unlink(ptrace_shared_file) == -1 && errno != ENOENT) {
157  	          mtcp_printf("delete_file: unlink failed: %s\n",
158  	                      strerror(errno));
159  	          mtcp_abort();
160  	        }
161  	        break;
162  	      }
163  	      case 1: {
164  	        if (unlink(ptrace_setoptions_file) == -1 && errno != ENOENT) {
165  	          mtcp_printf("delete_file: unlink failed: %s\n",
166  	                      strerror(errno));
167  	          mtcp_abort();
168  	        }
169  	        break;
170  	      }
171  	      case 2: {
172  	        if (unlink(checkpoint_threads_file) == -1 && errno != ENOENT) {
173  	          mtcp_printf("delete_file: unlink failed: %s\n",
174  	                      strerror(errno));
175  	          mtcp_abort();
176  	        }
177  	        break;
178  	      }
179  	      default: {
180  	        mtcp_printf ("delete_file: unknown option\n");
181  	      }
182  	    }
183  	  }
184  	}
185  	
186  	void ptrace_remove_notexisted()
187  	{
188  	  int i;
189  	  struct ptrace_tid_pairs temp;
190  	
191  	  DPRINTF(("<<<<<<<<<<< start ptrace_remove_notexisted %d\n", GETTID()));
192  	
193  	  for (i = 0; i < ptrace_pairs_count; i++) {
194  	    int tid = ptrace_pairs[i].inferior;
195  	    char pstate = procfs_state(tid);
196  	    DPRINTF(("checking status of %d = %c\n",tid,pstate));
197  	    if( pstate == 0) {
198  	      // process not exist
199  	      if ( i != (ptrace_pairs_count - 1)) {
200  	        temp = ptrace_pairs[i];
201  	        ptrace_pairs[i] = ptrace_pairs[ptrace_pairs_count - 1];
202  	        ptrace_pairs[ptrace_pairs_count - 1] = temp;
203  	        reset_ptrace_pairs_entry (ptrace_pairs_count - 1);
204  	        i--;
205  	        ptrace_pairs_count--;
206  	      }
207  	      else {
208  	        reset_ptrace_pairs_entry (ptrace_pairs_count - 1);
209  	        ptrace_pairs_count --;
210  	        break;
211  	      }
212  	    }
213  	  }
214  	
215  	  print_ptrace_pairs ();
216  	  DPRINTF((">>>>>>>>>>> done ptrace_remove_notexisted %d\n", GETTID()));
217  	}
218  	
219  	void ptrace_attach_threads(int isRestart)
220  	{
221  	  pid_t superior;
222  	  pid_t inferior;
223  	  int last_command;
224  	  int singlestep_waited_on;
225  	  struct user_regs_struct regs;
226  	  long peekdata;
227  	  long low, upp;
228  	  int status;
229  	  unsigned long addr;
230  	  unsigned long int eflags;
231  	  int i;
232  	
233  	  DPRINTF(("attach started %d\n", GETTID()));
234  	
235  	  /*
236  	  for (i = 0; i < ptrace_pairs_count; i++) {
237  	    mtcp_printf("tid = %d superior = %d inferior = %d last_command = %d\n", GETTID(), ptrace_pairs[i].superior, ptrace_pairs[i].inferior, ptrace_pairs[i].last_command); 
238  	  }
239  	  */
240  	  for (i = 0; i < ptrace_pairs_count; i++) {
241  	
242  	    superior = ptrace_pairs[i].superior;
243  	    inferior = ptrace_pairs[i].inferior;
244  	    last_command = ptrace_pairs[i].last_command;
245  	    singlestep_waited_on = ptrace_pairs[i].singlestep_waited_on;
246  	
247  	    char inferior_st = ptrace_pairs[i].inferior_st;
248  	
249  	//    kill(inferior,0);
250  	    if (superior == GETTID()) {
251  	
252  	      DPRINTF (("(attach) tid = %d superior = %d inferior = %d\n",
253  	              GETTID(), (int)superior, (int)inferior));
254  	      // we must make sure the inferior process was created 
255  	
256  	      sem_wait( &__sem);
257  	      if (only_once == 0) {
258  	        have_file (superior);
259  	        only_once = 1;
260  	      }
261  	    sem_post( &__sem);
262  	    if(  is_checkpoint_thread(inferior)) {
263  	      have_file (inferior);
264  	      DPRINTF(("ptrace_attach_threads: attach to checkpoint thread: %d\n",inferior));
265  	        //sleep(5);
266  	      is_ptrace_local = 1;
267  	      if (ptrace(PTRACE_ATTACH, inferior, 0, 0) == -1) {
268  	        DPRINTF(("PTRACE_ATTACH failed for parent = %d child = %d\n", (int)superior, (int)inferior));
269  	        perror("ptrace_attach_threads: PTRACE_ATTACH for CKPT failed");
270  	        while(1);
271  	        mtcp_abort();
272  	      }
273  	      is_waitpid_local = 1;
274  	      if (waitpid(inferior, &status, __WCLONE) == -1) {
275  	          perror("ptrace_attach_threads: waitpid for ckpt failed\n");
276  	          mtcp_abort();
277  	      }
278  	      if (WIFEXITED(status)) {
279  	        DPRINTF(("The reason for ckpt child death was %d\n",WEXITSTATUS(status)));
280  	      }else if(WIFSIGNALED(status)) {
281  	        DPRINTF(("The reason for ckpt child death was signal %d\n",WTERMSIG(status)));
282  	      }
283  	
284  	      DPRINTF(("ptrace_attach_threads: preCheckpoint state = %c\n",inferior_st));
285  	      if( inferior_st != 'T' ){
286  	        is_ptrace_local = 1;
287  	        if (ptrace(PTRACE_CONT, inferior, 0, 0) < 0) {
288  	          perror("ptrace_attach_threads: PTRACE_CONT failed");
289  	          mtcp_abort();
290  	        }
291  	      }      continue;
292  	    }
293  	
294  	
295  	      is_ptrace_local = 1;
296  	      if (ptrace(PTRACE_ATTACH, inferior, 0, 0) == -1) {
297  	        mtcp_printf("PTRACE_ATTACH failed for parent = %d child = %d\n", (int)superior, (int)inferior);
298  	        perror("ptrace_attach_threads: PTRACE_ATTACH failed");
299  	          mtcp_abort();
300  	      }
301  	      create_file (inferior);
302  	      while(1) {
303  	//        mtcp_printf("new iter for sup=%d, inf=%d\n",superior,inferior);
304  	        is_waitpid_local = 1;
305  	        if( waitpid(inferior, &status, 0 ) == -1) {
306  	          is_waitpid_local = 1;
307  	          if( waitpid(inferior, &status, __WCLONE ) == -1) {
308  	            while(1);
309  	            perror("ptrace_attach_threads: waitpid failed\n");
310  	            mtcp_abort();
311  	          }
312  	        }
313  	        if (WIFEXITED(status)) {
314  	          DPRINTF(("The reason for childs death was %d\n",WEXITSTATUS(status)));
315  	        }else if(WIFSIGNALED(status)) {
316  	          DPRINTF(("The reason for child's death was signal %d\n",WTERMSIG(status)));
317  	        }
318  	
319  	        if (ptrace(PTRACE_GETREGS, inferior, 0, &regs) < 0) {
320  	          perror("ptrace_attach_threads: PTRACE_GETREGS failed");
321  	          mtcp_abort();
322  	        }
323  	#ifdef __x86_64__ 
324  	        peekdata = ptrace(PTRACE_PEEKDATA, inferior, regs.rip, 0);
325  	#else
326  	        peekdata = ptrace(PTRACE_PEEKDATA, inferior, regs.eip, 0);
327  	#endif
328  	        low = peekdata & 0xff;
329  	        peekdata >>=8;
330  	        upp = peekdata & 0xff;
331  	
332  	#ifdef __x86_64__
333  	        if ((low == 0xf) && (upp == 0x05) && (regs.rax == 0xf)) {
334  	          /* This code is yet to be written */
335  	          if ( isRestart ) {
336  	            if (last_command == PTRACE_SINGLESTEP_COMMAND ) {
337  	              if (regs.eax == DMTCP_SYS_sigreturn) {
338  	                addr = regs.esp;
339  	              }
340  	              else {
341  	                DPRINTF(("SYS_RT_SIGRETURN\n"));
342  	                //UNTESTED -> TODO; gdb very unclear
343  	                addr = regs.esp + 8;
344  	                addr = ptrace(PTRACE_PEEKDATA, inferior, addr, 0);
345  	                addr += 20;
346  	              }
347  	              addr += EFLAGS_OFFSET;
348  	              errno = 0;
349  	              if ((eflags = ptrace(PTRACE_PEEKDATA, inferior, (void *)addr, 0)) < 0) {
350  	                if (errno != 0) {
351  	                  perror ("ptrace_attach_threads: PTRACE_PEEKDATA failed");
352  	                  mtcp_abort ();
353  	                }
354  	              }
355  	              eflags |= 0x0100;
356  	              printf("inferior = %d addr = %ld eflags = %ld \n", inferior, addr, eflags);
357  	              if (ptrace(PTRACE_POKEDATA, inferior, addr, eflags) < 0) {
358  	                perror("ptrace_attach_threads: PTRACE_POKEDATA failed");
359  	                mtcp_abort();
360  	              }
361  	            }
362  	            else if (inferior_st != 'T' ) {
363  	/*
364  	TODO: remove in future as GROUP restore becames stable
365  	- Artem              
366  	              if (getsid(inferior) == getsid(superior)) {
367  	                if ( tcsetpgrp(STDIN_FILENO, inferior) == -1)
368  	                {
369  	                         perror("ptrace_attach_threads: tcsetpgrp failed");
370  	                         mtcp_abort();
371  	                }
372  	              }
373  	*/
374  	              is_ptrace_local = 1;
375  	              if (ptrace(PTRACE_CONT, inferior, 0, 0) < 0) {
376  	                perror("ptrace_attach_threads: PTRACE_CONT failed");
377  	                mtcp_abort();
378  	              }
379  	            }
380  	          } else {
381  	            if (inferior_st != 'T')
382  	            {
383  	              if (getsid(inferior) == getsid(superior)) {
384  	                if ( tcsetpgrp(STDIN_FILENO, inferior) == -1)
385  	                {
386  	                         perror("ptrace_attach_threads: tcsetpgrp failed");
387  	                         mtcp_abort();
388  	                }
389  	              }
390  	              is_ptrace_local = 1;
391  	              if (ptrace(PTRACE_CONT, inferior, 0, 0) < 0) {
392  	                perror("ptrace_attach_threads: PTRACE_CONT failed");
393  	                mtcp_abort();
394  	              }
395  	            }
396  	          }
397  	
398  	        if (inferior_st == 'T') {
399  	          /* this is needed because we are hitting the same breakpoint 
400  	             twice if we were ckpt at a breakpoint
401  	             info breakpoint was giving incorrect values 
402  	           */
403  	          is_ptrace_local = 1;
404  	          if (ptrace(PTRACE_SINGLESTEP, inferior, 0, 0) < 0) {
405  	            perror("ptrace_attach_threads: PTRACE_SINGLESTEP failed");
406  	            mtcp_abort();
407  	          }
408  	          is_waitpid_local = 1;
409  	          if( waitpid(inferior, &status, 0 ) == -1) {
410  	            is_waitpid_local = 1;
411  	            if( waitpid(inferior, &status, __WCLONE ) == -1) {
412  	              while(1);
413  	              perror("ptrace_attach_threads: waitpid failed\n");
414  	              mtcp_abort();
415  	            }
416  	          }
417  	        }
418  	          break;
419  	        }
420  	        #else
421  	        if (((low == 0xcd) && (upp == 0x80)) &&
422  	                  ((regs.eax == DMTCP_SYS_sigreturn) ||
423  	                   (regs.eax == DMTCP_SYS_rt_sigreturn))) {
424  	          if ( isRestart ) {
425  	            if (last_command == PTRACE_SINGLESTEP_COMMAND ) {
426  	              if (regs.eax == DMTCP_SYS_sigreturn) {
427  	                addr = regs.esp;
428  	              }
429  	              else {
430  	                DPRINTF(("SYS_RT_SIGRETURN\n"));
431  	                //UNTESTED -> TODO; gdb very unclear
432  	                addr = regs.esp + 8;
433  	                addr = ptrace(PTRACE_PEEKDATA, inferior, addr, 0);
434  	                addr += 20;
435  	              }
436  	              addr += EFLAGS_OFFSET;
437  	              errno = 0;
438  	              if ((eflags = ptrace(PTRACE_PEEKDATA, inferior, (void *)addr, 0)) < 0) {
439  	                if (errno != 0) {
440  	                  perror ("ptrace_attach_threads: PTRACE_PEEKDATA failed");
441  	                  mtcp_abort ();
442  	                }
443  	              }
444  	              eflags |= 0x0100;
445  	              if (ptrace(PTRACE_POKEDATA, inferior, (void *)addr, eflags) < 0) {
446  	                perror("ptrace_attach_threads: PTRACE_POKEDATA failed");
447  	                mtcp_abort();
448  	              }
449  	            } else if (inferior_st != 'T') {
450  	              if (getsid(inferior) == getsid(superior)) {
451  	                if ( tcsetpgrp(STDIN_FILENO, inferior) == -1)
452  	                {
453  	                         perror("ptrace_attach_threads: tcsetpgrp failed");
454  	                         mtcp_abort();
455  	                }
456  	              }
457  	              is_ptrace_local = 1;
458  	              if (ptrace(PTRACE_CONT, inferior, 0, 0) < 0) {
459  	                perror("ptrace_attach_threads: PTRACE_CONT failed");
460  	                mtcp_abort();
461  	              }
462  	            }
463  	          } else {
464  	            if (inferior_st != 'T') {
465  	              if (getsid(inferior) == getsid(superior)) {
466  	                 if ( tcsetpgrp(STDIN_FILENO, inferior) == -1)
467  	                 {
468  	                         perror("ptrace_attach_threads: tcsetpgrp failed");
469  	                         mtcp_abort();
470  	                 }
471  	              }
472  	              is_ptrace_local = 1;
473  	              if (ptrace(PTRACE_CONT, inferior, 0, 0) < 0) {
474  	                perror("ptrace_attach_threads: PTRACE_CONT failed");
475  	                mtcp_abort();
476  	              }
477  	            }
478  	          }
479  	
480  	
481  	        if (inferior_st == 'T') {
482  	          /* this is needed because we are hitting the same breakpoint 
483  	             twice if we were ckpt at a breakpoint
484  	             info breakpoint was giving incorrect values 
485  	           */
486  	          is_ptrace_local = 1;
487  	          if (ptrace(PTRACE_SINGLESTEP, inferior, 0, 0) < 0) {
488  	            perror("ptrace_attach_threads: PTRACE_SINGLESTEP failed");
489  	            mtcp_abort();
490  	          }
491  	          is_waitpid_local = 1;
492  	          if( waitpid(inferior, &status, 0 ) == -1) {
493  	            is_waitpid_local = 1;
494  	            if( waitpid(inferior, &status, __WCLONE ) == -1) {
495  	              while(1);
496  	              perror("ptrace_attach_threads: waitpid failed\n");
497  	              mtcp_abort();
498  	            }
499  	          }
500  	        }
501  	          break;
502  	        }
503  	        #endif
504  	        is_ptrace_local = 1;
505  	        if (ptrace(PTRACE_SINGLESTEP, inferior, 0, 0) < 0) {
506  	          perror("ptrace_attach_threads: PTRACE_SINGLESTEP failed");
507  	          mtcp_abort();
508  	        }
509  	      }
510  	    }
511  	    else if (inferior == GETTID()) {
512  	
513  	      create_file (superior);
514  	      have_file (inferior);
515  	    }
516  	  }
517  	  DPRINTF(("ptrace_attach_threads: finished for %d\n", GETTID()));
518  	}
519  	
520  	void ptrace_detach_checkpoint_threads ()
521  	{
522  	  int i,ret;
523  	  pid_t tgid;
524  	
525  	  // Release only checkpoint threads
526  	  for (i = 0; i < ptrace_pairs_count; i++) {
527  	    int tid = ptrace_pairs[i].inferior;
528  	    int sup = ptrace_pairs[i].superior;
529  	    tgid = is_checkpoint_thread (tid);
530  	    if ((sup == GETTID()) && tgid ) {
531  	      DPRINTF(("ptrace_detach_checkpoint_threads: ptrace_detach_ckpthread(%d,%d,%d)\n",
532  	            tgid,tid,sup));
533  	      if( ret = ptrace_detach_ckpthread(tgid,tid,sup) ){
534  	        if( ret == -ENOENT ){
535  	          DPRINTF(("%s: process not exist %d\n",__FUNCTION__,tid));
536  	        }
537  	        mtcp_abort();
538  	      }
539  	    }
540  	  }
541  	  DPRINTF((">>>>>>>>> done ptrace_detach_checkpoint_threads %d\n", GETTID()));
542  	}
543  	
544  	void ptrace_detach_user_threads ()
545  	{
546  	  int i;
547  	  int status = 0;
548  	
549  	  for(i = 0; i < ptrace_pairs_count; i++) {
550  	    /*
551  	    mtcp_printf("tid = %d superior = %d inferior = %d last_command = %d\n", GETTID(), ptrace_pairs[i].superior, 
552  	        ptrace_pairs[i].inferior, ptrace_pairs[i].last_command);
553  	    */
554  	    if( is_checkpoint_thread(ptrace_pairs[i].inferior) ){
555  	      DPRINTF(("ptrace_detach_user_threads: SKIP checkpoint thread %d\n",ptrace_pairs[i].inferior));
556  	      continue;
557  	    }
558  	
559  	    if( ptrace_pairs[i].superior == GETTID()) {
560  	      char pstate;
561  	      // required for all user threads to get SIGUSR2 from their checkpoint thread
562  	      // TODO: to be removed by waiting for the signal to have been delivered
563  	      // sleep(PTRACE_SLEEP_INTERVAL);
564  	      int tid = ptrace_pairs[i].inferior, tpid;
565  	      DPRINTF(("start waiting on %d\n",tid));
566  	
567  	      // Check if status of this thread already read by debugger
568  	      pstate = procfs_state(tid);
569  	      DPRINTF(("procfs_state(%d) = %c\n",tid,pstate));
570  	      if( pstate == 0){
571  	      // process not exist
572  	        mtcp_printf("%s: process not exist %d\n",__FUNCTION__,tid);
573  	        mtcp_abort();
574  	      } else if( pstate == 'T'){
575  	        // There can be posibility that GDB (or other) reads status of this
576  	        // thread before us. So we will block. We don't want that.
577  	        // Read anyway but without hang
578  	        DPRINTF(("!!!! Process already stopped !!!!\n"));
579  	
580  	        is_waitpid_local = 1;
581  	        tpid = waitpid (tid, &status, WNOHANG);
582  	        if(tpid == -1 && errno == ECHILD){
583  	          DPRINTF(("Check cloned process\n"));
584  	          // Try again with __WCLONE to check cloned processes.
585  	is_waitpid_local = 1;
586  	          if( (tpid = waitpid (tid, &status, __WCLONE | WNOHANG ) ) == -1 ){
587  	            DPRINTF(("ptrace_detach_checkpoint_threads: waitpid(..,__WCLONE): : %s\n",
588  	                        strerror(errno)));
589  	          }
590  	        }
591  	
592  	        DPRINTF(("tgid = %d, tpid=%d,stopped=%d is_sigstop=%d,signal=%d\n",
593  	            tid,tpid,WIFSTOPPED(status),WSTOPSIG(status) == SIGSTOP,WSTOPSIG(status)));
594  	      }else{
595  	        // Process not in stopped state. We are in signal handler of GDB thread which waits for status change 
596  	        // for this process. Now it is safe to call blocking waitpid.
597  	
598  	        DPRINTF(("!!!! Process is not stopped yet !!!!\n"));
599  	        is_waitpid_local = 1;
600  	        tpid = waitpid (tid, &status, 0);
601  	        if(tpid == -1 && errno == ECHILD){
602  	          DPRINTF(("Check cloned process\n"));
603  	          // Try again with __WCLONE to check cloned processes.
604  	          is_waitpid_local = 1;
605  	          if( (tpid = waitpid (tid, &status, __WCLONE ) ) == -1 ){
606  	            mtcp_printf("ptrace_detach_checkpoint_threads: waitpid(..,__WCLONE): %s\n",
607  	                        strerror(errno));
608  	          }
609  	        }
610  	        DPRINTF(("tgid = %d, tpid=%d,stopped=%d is_sigstop=%d,signal=%d\n",
611  	            tid,tpid,WIFSTOPPED(status),WSTOPSIG(status) == SIGSTOP,WSTOPSIG(status)));
612  	        if(WIFSTOPPED(status)) {
613  	          if (WSTOPSIG(status) == MTCP_DEFAULT_SIGNAL)
614  	            DPRINTF(("user thread %d was stopped by the delivery of MTCP_DEFAULT_SIGNAL\n",tid));          else{  //we should never get here  
615  	            DPRINTF(("user thread %d was stopped by the delivery of %d\n", tid, WSTOPSIG(status))
616  	);
617  	          }
618  	        }else  //we should never end up here 
619  	          DPRINTF(("user thread %d was NOT stopped by a signal\n", ptrace_pairs[i].inferior));
620  	      }
621  	
622  	      if (( ptrace_pairs[i].last_command == PTRACE_SINGLESTEP_COMMAND ) &&
623  	          ( ptrace_pairs[i].singlestep_waited_on == FALSE )) {
624  	        //is_waitpid_local = 1;
625  	        has_status_and_pid = 1;
626  	        saved_status = status;
627  	        DPRINTF(("+++++++++++++++++++++++++ptrace_detach_user_threads: AFTER WAITPID %d\n",
628  	                 status));
629  	        ptrace_pairs[i].singlestep_waited_on = TRUE;
630  	        ptrace_pairs[i].last_command = PTRACE_UNSPECIFIED_COMMAND;
631  	      }
632  	
633  	      DPRINTF(("tid = %d detaching superior = %d from inferior = %d\n",
634  	               GETTID(), (int)ptrace_pairs[i].superior, (int)ptrace_pairs[i].inferior));
635  	      have_file (ptrace_pairs[i].inferior);
636  	      is_ptrace_local = 1;
637  	      if (ptrace(PTRACE_DETACH, ptrace_pairs[i].inferior, 0, MTCP_DEFAULT_SIGNAL) == -1) {
638  	        DPRINTF(("ptrace_detach_user_threads: parent = %d child = %d\n",
639  	                (int)ptrace_pairs[i].superior,
640  	                (int)ptrace_pairs[i].inferior));
641  	        DPRINTF(("ptrace_detach_user_threads: PTRACE_DETACH failed with error=%d",errno));
642  	      }
643  	    }
644  	  }
645  	  DPRINTF((">>>>>>>>> done ptrace_detach_user_threads %d\n", GETTID()));
646  	}
647  	
648  	void ptrace_lock_inferiors()
649  	{
650  	    char file[SYNCHRONIZATIONPATHLEN];
651  	    snprintf(file,SYNCHRONIZATIONPATHLEN,"%s/dmtcp_ptrace_unlocked.%d",dir,GETTID());
652  	    unlink(file);
653  	}
654  	
655  	void ptrace_unlock_inferiors()
656  	{
657  	    char file[SYNCHRONIZATIONPATHLEN];
658  	    int fd;
659  	    snprintf(file, SYNCHRONIZATIONPATHLEN, "%s/dmtcp_ptrace_unlocked.%d",dir,GETTID());
660  	    fd = creat(file,0644);
661  	    if( fd < 0 ){
662  	        mtcp_printf("init_lock: Error while creating lock file: %s\n",
663  	                    strerror(errno));
664  	        mtcp_abort();
665  	    }
666  	    close(fd);
667  	}
668  	
669  	void create_file(pid_t pid)
670  	{
671  	  char str[SYNCHRONIZATIONPATHLEN];
672  	  int fd;
673  	
674  	  memset(str, 0, SYNCHRONIZATIONPATHLEN);
675  	  sprintf(str, "%s/%d", dir, pid);
676  	
677  	  fd = open(str, O_CREAT|O_APPEND|O_WRONLY, 0644);
678  	  if (fd == -1) {
679  	    mtcp_printf("create_file: Error opening file %s\n: %s\n",
680  	                str, strerror(errno));
681  	    mtcp_abort();
682  	  }
683  	  if ( close(fd) != 0 ) {
684  	    mtcp_printf("create_file: Error closing file\n: %s\n",
685  	                strerror(errno));
686  	    mtcp_abort();
687  	  }
688  	}
689  	
690  	static void have_file(pid_t pid)
691  	{
692  	  char str[SYNCHRONIZATIONPATHLEN];
693  	  int fd;
694  	
695  	  memset(str, 0, SYNCHRONIZATIONPATHLEN);
696  	  sprintf(str, "%s/%d", dir, pid);
697  	  while(1) {
698  	    fd = open(str, O_RDONLY);
699  	    if (fd != -1) {
700  	        if (close(fd) != 0) {
701  	        mtcp_printf("have_file: Error closing file: %s\n",
702  	                    strerror(errno));
703  	        mtcp_abort();
704  	        }
705  	      if (unlink(str) == -1) {
706  	        mtcp_printf("have_file: unlink failed: %s\n",
707  	                    strerror(errno));
708  	        mtcp_abort();
709  	      }
710  	      break;
711  	    }
712  	    usleep(100);
713  	  }
714  	}
715  	
716  	void ptrace_wait4(pid_t pid)
717  	{    char file[SYNCHRONIZATIONPATHLEN];
718  	    struct stat buf;
719  	    snprintf(file,SYNCHRONIZATIONPATHLEN,"%s/dmtcp_ptrace_unlocked.%d",dir,pid);
720  	
721  	    DPRINTF(("%d: Start waiting for superior\n",GETTID()));
722  	    while( stat(file,&buf) < 0 ){
723  	      struct timespec ts;
724  	      DPRINTF(("%d: Superior is not ready\n",GETTID()));
725  	      ts.tv_sec = 0;
726  	      ts.tv_nsec = 100000000;
727  	      if( errno != ENOENT ){
728  	        mtcp_printf("prtrace_wait4: Unexpected error in stat: %d\n",errno);
729  	        mtcp_abort();
730  	      }
731  	      nanosleep(&ts,NULL);
732  	    }
733  	    DPRINTF(("%d: Superior unlocked us\n",GETTID()));
734  	}
735  	
736  	/*************************************************************************/
737  	/* Utilities for ptrace code                                             */
738  	/* IF ALL THESE FUNCTIONS MUST EXIST INSIDE mtcp.c AND NOT IN SEAPARATE  */
739  	/* FILE, THEN WE MUST RENAME THEM ALL WITH SOME PREFIX LIKE pt_          */
740  	/* (DIFFERENT NAMESPACE FROM REST OF FILE).  IF WE CAN MOVE THEM TO      */
741  	/* A DIFFERENT FILE, THAT WOULD BE EVEN BETTER.   - Gene                 */
742  	/*************************************************************************/
743  	static void reset_ptrace_pairs_entry ( int i )
744  	{
745  	  ptrace_pairs[i].last_command = PTRACE_UNSPECIFIED_COMMAND;
746  	  ptrace_pairs[i].singlestep_waited_on = FALSE;
747  	  ptrace_pairs[i].free = TRUE;
748  	  ptrace_pairs[i].inferior_st = 'u';
749  	}
750  	
751  	static void move_last_ptrace_pairs_entry_to_i ( int i )
752  	{
753  	  ptrace_pairs[i].superior = ptrace_pairs[ptrace_pairs_count-1].superior;
754  	  ptrace_pairs[i].inferior = ptrace_pairs[ptrace_pairs_count-1].inferior;
755  	  ptrace_pairs[i].last_command = ptrace_pairs[ptrace_pairs_count-1].last_command;
756  	  ptrace_pairs[i].singlestep_waited_on = ptrace_pairs[ptrace_pairs_count-1].singlestep_waited_on;
757  	  ptrace_pairs[i].free = ptrace_pairs[ptrace_pairs_count-1].free;
758  	  ptrace_pairs[i].inferior_st = ptrace_pairs[ptrace_pairs_count-1].inferior_st;
759  	}
760  	
761  	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
762  	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
763  	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
764  	 */
765  	void remove_from_ptrace_pairs ( pid_t superior, pid_t inferior )
766  	{
767  	  int i;
768  	  for (i = 0; i < ptrace_pairs_count; i++) {
769  	    if ((ptrace_pairs[i].superior == superior) && (ptrace_pairs[i].inferior == inferior)) {
770  	      break;
771  	    }
772  	  }
773  	  if (i == ptrace_pairs_count) return;
774  	  if (i != (ptrace_pairs_count-1)) {
775  	    pthread_mutex_lock(&ptrace_pairs_mutex);
776  	    move_last_ptrace_pairs_entry_to_i(i);
777  	    reset_ptrace_pairs_entry(ptrace_pairs_count-1);
778  	    ptrace_pairs_count--;
779  	    pthread_mutex_unlock(&ptrace_pairs_mutex);
780  	  }
781  	  else {
782  	    pthread_mutex_lock(&ptrace_pairs_mutex);
783  	    reset_ptrace_pairs_entry(i);
784  	    ptrace_pairs_count--;
785  	    pthread_mutex_unlock(&ptrace_pairs_mutex);
786  	  }
787  	}
788  	
789  	static int is_in_ptrace_pairs ( pid_t superior, pid_t inferior )
790  	{
791  	  int i;
792  	  for (i = 0; i < ptrace_pairs_count; i++) {
793  	    if ((ptrace_pairs[i].superior == superior) && (ptrace_pairs[i].inferior == inferior)) return i;
794  	  }
795  	  return -1;
796  	}
797  	
798  	static void add_to_ptrace_pairs ( pid_t superior, pid_t inferior, int last_command, int singlestep_waited_on )
799  	{
800  	  struct ptrace_tid_pairs new_pair;
801  	
802  	  new_pair.superior = superior;
803  	  new_pair.inferior = inferior;
804  	  new_pair.last_command = last_command;
805  	  new_pair.singlestep_waited_on = singlestep_waited_on;
806  	  new_pair.free = FALSE;
807  	  new_pair.inferior_st = 'u';
808  	  new_pair.eligible_for_deletion = TRUE;
809  	
810  	  pthread_mutex_lock(&ptrace_pairs_mutex);
811  	  ptrace_pairs[ptrace_pairs_count] = new_pair;
812  	  ptrace_pairs_count++;
813  	  pthread_mutex_unlock(&ptrace_pairs_mutex);
814  	}
815  	
816  	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
817  	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
818  	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
819  	 */
820  	void handle_command ( pid_t superior, pid_t inferior, int last_command )
821  	{
822  	  int index = is_in_ptrace_pairs ( superior, inferior );
823  	  if ( index >= 0 ) {
824  	    ptrace_pairs[index].last_command = last_command;
825  	    if ( last_command == PTRACE_SINGLESTEP_COMMAND ) ptrace_pairs[index].singlestep_waited_on = FALSE;
826  	  }
827  	  else {
828  	    /* not in the ptrace pairs array; reason: inferior did an PTRACE_TRACEME and now the superior is issuing commands */
829  	    add_to_ptrace_pairs( superior, inferior, last_command, FALSE );
830  	  }
831  	}
832  	
833  	enum {
834  	  SORT_BY_SUPERIOR = 0,
835  	  SORT_BY_INFERIOR
836  	};
837  	
838  	static int find_slot (int seed) {
839  	  int i;
840  	  pid_t inferior;
841  	  for (i = seed; i >= 0; i--) {
842  	    inferior = ptrace_pairs[i].inferior;
843  	    if (!is_checkpoint_thread(inferior))
844  	      return i;   
845  	  }
846  	  return -1;
847  	}
848  	
849  	/* This function moves all checkpoint threads at the end of ptrace_pairs array.
850  	 * It returns the index in ptrace_pairs array where ckpt threads are located. */
851  	static int move_ckpt_threads_towards_end () {
852  	  int i;
853  	  struct ptrace_tid_pairs temp;
854  	  pid_t superior;
855  	  pid_t inferior;
856  	  int limit = ptrace_pairs_count;
857  	  int ckpt_threads = 0;
858  	  
859  	  int slot = find_slot(ptrace_pairs_count - 1);
860  	  for (i = 0; i < limit; i++) {
861  	    inferior = ptrace_pairs[i].inferior;
862  	    if (is_checkpoint_thread(inferior)) {
863  	      ckpt_threads++;
864  	      if (slot > i) {
865  	        temp = ptrace_pairs[i];
866  	        ptrace_pairs[i] = ptrace_pairs[slot];
867  	        ptrace_pairs[slot] = temp;
868  	        limit = slot;
869  	        slot = find_slot(slot - 1);
870  	      }
871  	    }
872  	  }
873  	  return ckpt_threads;
874  	}
875  	
876  	static pid_t get_pid_by_key (int key, int index) {
877  	  if (key == SORT_BY_SUPERIOR)
878  	    return ptrace_pairs[index].superior;
879  	  else if (key == SORT_BY_INFERIOR)
880  	    return ptrace_pairs[index].inferior;
881  	  return -1;
882  	}
883  	
884  	static void sort_ptrace_pairs_by_key (int key, int begin, int end) {
885  	  int i, j;
886  	  pid_t upper_pid;
887  	  pid_t inner_pid;
888  	  pid_t temp_pid;
889  	  struct ptrace_tid_pairs temp;
890  	  for (i = begin; i < (end - 1); i++) {
891  	    upper_pid = get_pid_by_key (key, i);
892  	    for (j = i + 1; j < end; j++) {
893  	      inner_pid = get_pid_by_key (key, j);
894  	      if (upper_pid < inner_pid) {
895  	        temp = ptrace_pairs[i];
896  	        ptrace_pairs[i] = ptrace_pairs[j];
897  	        ptrace_pairs[j] = temp; 
898  	        temp_pid = upper_pid;
899  	        upper_pid = inner_pid;
900  	        inner_pid = temp_pid;
901  	      }
902  	    }  
903  	  }
904  	}
905  	
906  	static void sort_ptrace_pairs_within_limit (int begin, int end) {
907  	  sort_ptrace_pairs_by_key (SORT_BY_SUPERIOR, begin, end);
908  	  int ref_superior;
909  	  int superior;
910  	  int inferior;
911  	  int start = begin;
912  	  int i;
913  	  ref_superior = ptrace_pairs[0].superior;
914  	  for (i = (start + 1); i < end; i++) {
915  	    superior = ptrace_pairs[i].superior;
916  	    if (superior != ref_superior) {
917  	      sort_ptrace_pairs_by_key (SORT_BY_INFERIOR, start, i);
918  	      ref_superior = superior;
919  	      start = i;
920  	    }
921  	  }
922  	  sort_ptrace_pairs_by_key (SORT_BY_INFERIOR, start, end);
923  	}
924  	
925  	static void sort_ptrace_pairs () {
926  	  if (ptrace_pairs_count <= 1)
927  	    return;
928  	  int limit = ptrace_pairs_count - move_ckpt_threads_towards_end ();
929  	  /* sort all non-checkpoint threads*/
930  	  sort_ptrace_pairs_within_limit (0, limit);
931  	  /* sort all checkpoint threads */
932  	  sort_ptrace_pairs_within_limit (limit, ptrace_pairs_count);
933  	}
934  	
935  	static void print_ptrace_pairs ()
936  	{
937  	  int i;
938  	  DPRINTF(("\n\n"));
939  	  for ( i = 0; i < ptrace_pairs_count; i++ )
940  	     DPRINTF(("tid = %d superior = %d inferior = %d \n",
941  	              GETTID(), (int)ptrace_pairs[i].superior, (int)ptrace_pairs[i].inferior));
942  	  DPRINTF(("tid = %d ptrace_pairs_count = %d \n", GETTID(), ptrace_pairs_count));
943  	  DPRINTF(("\n\n"));
944  	}
945  	
946  	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
947  	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
948  	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
949  	 */
950  	
951  	
952  	void write_info_to_file (int file, pid_t superior, pid_t inferior)
953  	{
954  	  int fd;
955  	  struct flock lock;
956  	
957  	  switch (file) {
958  	    case 0: {
959  	      fd = open(ptrace_shared_file, O_CREAT|O_APPEND|O_WRONLY|O_FSYNC, 0644);
960  	      break;
961  	    }
962  	    case 1: {
963  	      fd = open(ptrace_setoptions_file, O_CREAT|O_APPEND|O_WRONLY|O_FSYNC, 0644);
964  	      break;
965  	    }
966  	    case 2: {
967  	      fd = open(checkpoint_threads_file, O_CREAT|O_APPEND|O_WRONLY|O_FSYNC, 0644);
968  	      break;
969  	    }
970  	    default: {
971  	      mtcp_printf ("write_info_to_file: unknown option\n");
972  	      return;
973  	    }
974  	  }
975  	
976  	  if (fd == -1) {
977  	    mtcp_printf("write_info_to_file: Error opening file\n: %s\n",
978  	                strerror(errno));
979  	    abort();
980  	  }
981  	
982  	  lock.l_type = F_WRLCK;
983  	  lock.l_whence = SEEK_CUR;
984  	  lock.l_start = 0;
985  	  lock.l_len = 0;
986  	  lock.l_pid = getpid();
987  	
988  	  if (fcntl(fd, F_GETLK, &lock ) == -1) {
989  	    mtcp_printf("write_info_to_file: Error acquiring lock: %s\n",
990  	                strerror(errno));
991  	    abort();
992  	  }
993  	
994  	  if (write(fd, &superior, sizeof(pid_t)) == -1) {
995  	    mtcp_printf("write_info_to_file: Error writing to file: %s\n",
996  	                strerror(errno));
997  	    abort();
998  	  }
999  	  if (write(fd, &inferior, sizeof(pid_t)) == -1) {
1000 	    mtcp_printf("write_info_to_file: Error writing to file: %s\n",
1001 	                strerror(errno));
1002 	    abort();
1003 	  }
1004 	
1005 	  lock.l_type = F_UNLCK;
1006 	  lock.l_whence = SEEK_CUR;
1007 	  lock.l_start = 0;
1008 	  lock.l_len = 0;
1009 	
1010 	  if (fcntl(fd, F_SETLK, &lock) == -1) {
1011 	    mtcp_printf("write_info_to_file: Error releasing lock: %s\n",
1012 	                strerror(errno));
1013 	    abort();
1014 	  }
1015 	  if (close(fd) != 0) {
1016 	    mtcp_printf("write_info_to_file: Error closing file: %s\n",
1017 	                strerror(errno));
1018 	    abort();
1019 	  }
1020 	}
1021 	
1022 	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
1023 	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
1024 	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
1025 	 */
1026 	void writeptraceinfo (pid_t superior, pid_t inferior)
1027 	{
1028 	  int index = is_in_ptrace_pairs ( superior, inferior );
1029 	  if (index == -1 ) {
1030 	    write_info_to_file (0, superior, inferior);
1031 	    add_to_ptrace_pairs ( superior, inferior, PTRACE_UNSPECIFIED_COMMAND, FALSE );
1032 	  }
1033 	}
1034 	
1035 	/***********************************************************************
1036 	 * This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
1037 	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
1038 	 * WE'RE A GUEST IN THE USER'S PROCESS.    - Gene
1039 	 ***********************************************************************/
1040 	void set_singlestep_waited_on ( pid_t superior, pid_t inferior,
1041 	                                       int value )
1042 	{
1043 	  int index = is_in_ptrace_pairs ( superior, inferior );
1044 	  if (( index >= 0 ) && ( ptrace_pairs[index].last_command == PTRACE_SINGLESTEP_COMMAND ))
1045 	    ptrace_pairs[index].singlestep_waited_on = value;
1046 	  if (index >= 0)
1047 	        ptrace_pairs[index].last_command = PTRACE_UNSPECIFIED_COMMAND;
1048 	}
1049 	
1050 	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
1051 	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
1052 	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
1053 	 */
1054 	int get_is_waitpid_local ()
1055 	{
1056 	  return is_waitpid_local;
1057 	}
1058 	
1059 	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
1060 	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
1061 	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
1062 	 */
1063 	int get_is_ptrace_local ()
1064 	{
1065 	  return is_ptrace_local;
1066 	}
1067 	
1068 	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
1069 	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
1070 	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
1071 	 */
1072 	void unset_is_waitpid_local ()
1073 	{
1074 	  is_waitpid_local = 0;
1075 	}
1076 	
1077 	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
1078 	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
1079 	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
1080 	 */
1081 	void unset_is_ptrace_local ()
1082 	{
1083 	  is_ptrace_local = 0;
1084 	}
1085 	
1086 	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
1087 	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
1088 	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
1089 	 */
1090 	pid_t get_saved_pid ()
1091 	{
1092 	  return saved_pid;
1093 	}
1094 	
1095 	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
1096 	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
1097 	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
1098 	 */
1099 	int get_saved_status ()
1100 	{
1101 	  return saved_status;
1102 	}
1103 	
1104 	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
1105 	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
1106 	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
1107 	 */
1108 	int get_has_status_and_pid ()
1109 	{
1110 	  return has_status_and_pid;
1111 	}
1112 	
1113 	/* This is called by DMTCP.  BUT IT MUST THEN HAVE A PREFIX LIKE mtcp_
1114 	 * IN FRONT OF IT.  WE DON'T WANT TO POLLUTE THE USER'S NAMESPACE.
1115 	 * WE'RE A GUEST IN HIS PROCESS.    - Gene
1116 	 */
1117 	void reset_pid_status ()
1118 	{
1119 	  saved_pid = -1;
1120 	  saved_status = -1;
1121 	  has_status_and_pid = 0;
1122 	}
1123 	
1124 	static int is_alive (pid_t pid)
1125 	{
1126 	  char str[20];
1127 	  int fd;
1128 	
1129 	  memset(str, 0, 20);
1130 	    sprintf(str, "/proc/%d/maps", pid);
1131 	
1132 	  fd = open(str, O_RDONLY);
1133 	    if (fd != -1) {
1134 	      if ( close(fd) != 0 ) {
1135 	      mtcp_printf("is_alive: Error closing file: %s\n",
1136 	                  strerror(errno));
1137 	      mtcp_abort();
1138 	      }
1139 	    return 1;
1140 	  }
1141 	  return 0;
1142 	}
1143 	
1144 	static int is_in_ckpt_threads (pid_t pid)
1145 	{
1146 	  int i;
1147 	  for (i = 0; i < ckpt_threads_count; i++) {
1148 	    if (ckpt_threads[i].pid == pid) return 1;
1149 	  }
1150 	  return 0;
1151 	}
1152 	static void print_ckpt_threads ()
1153 	{
1154 	  int i;
1155 	  for (i = 0; i < ckpt_threads_count; i++)
1156 	    DPRINTF(("moa = %d pid = %d tid = %d \n",
1157 	             GETTID(), ckpt_threads[i].pid, ckpt_threads[i].tid));
1158 	}
1159 	
1160 	char procfs_state(int tid)
1161 	{
1162 	  char name[64];
1163 	  char sbuf[256], *S, *tmp;
1164 	  char state;
1165 	  int num_read, fd;
1166 	
1167 	  sprintf(name,"/proc/%d/stat",tid);
1168 	  fd = open(name, O_RDONLY, 0);
1169 	  if( fd < 0 ){
1170 	    mtcp_printf("procfs_status: cannot open %s\n",name);
1171 	    return 0;
1172 	  }
1173 	  /* THIS CODE CAN'T WORK RELIABLY.  SUPPOSE read() RETURNS 0,
1174 	   * OR -1 WITH EAGAIN OR EINTR?  LOOK FOR EXAMPLES IN
1175 	   *  mtcp_restart_nolibc.c:readfile() OR ELSEWHERE.   - Gene
1176 	   */
1177 	  num_read = read(fd, sbuf, sizeof sbuf - 1);
1178 	  close(fd);
1179 	  if(num_read<=0) {
1180 	    return 0;
1181 	  }
1182 	  sbuf[num_read] = '\0';
1183 	
1184 	  S = strchr(sbuf, '(') + 1;
1185 	  tmp = strrchr(S, ')');
1186 	  S = tmp + 2;                 // skip ") "
1187 	
1188 	  /* YOU SEEM TO WANT S[0] HERE.  WHY sscanf?  ALSO WHY ARE WE USING
1189 	   * CAPS ("S") FOR VAR NAME?  - Gene
1190 	   */
1191 	  sscanf(S, "%c", &state);
1192 	
1193 	  return state;
1194 	}
1195 	
1196 	void process_ptrace_info (pid_t *delete_ptrace_leader,
1197 	        int *has_ptrace_file,
1198 	        pid_t *delete_setoptions_leader, int *has_setoptions_file,
1199 	        pid_t *delete_checkpoint_leader, int *has_checkpoint_file)
1200 	{
1201 	  int ptrace_fd = -1;
1202 	  siginfo_t infoop;
1203 	  int i;
1204 	  pid_t superior;
1205 	  pid_t inferior;
1206 	  int setoptions_fd = -1;
1207 	  struct ptrace_tid_pairs temp;
1208 	  int checkpoint_fd = -1;
1209 	  pid_t pid;
1210 	  pid_t tid;
1211 	  struct ckpt_thread ckpt_thread_temp;
1212 	
1213 	  DPRINTF((">>>>>>>>>>>>>>>>>>>>>>>>>>>>process_ptrace_info: thread = %d\n", GETTID()));
1214 	
1215 	// TODO: consider that only checkpoint thread now runs this code  
1216 	//  if (thread == motherofall) {
1217 	    // read the information from the ptrace file  
1218 	    ptrace_fd = open(ptrace_shared_file, O_RDONLY);
1219 	    if (ptrace_fd != -1) {
1220 	      *has_ptrace_file = 1;
1221 	      while (readall(ptrace_fd, &superior, sizeof(pid_t)) > 0) {
1222 	        readall(ptrace_fd, &inferior, sizeof(pid_t));
1223 	        if ( is_in_ptrace_pairs(superior, inferior) == -1 ) {
1224 	          add_to_ptrace_pairs(superior, inferior, PTRACE_UNSPECIFIED_COMMAND, FALSE);
1225 	        }
1226 	        if (*delete_ptrace_leader < superior)
1227 	          *delete_ptrace_leader = superior;
1228 	      }
1229 	        if ( close(ptrace_fd) != 0 ) {
1230 	        mtcp_printf("process_ptrace_info: Error closing file. Error: %s\n", strerror(errno));
1231 	        mtcp_abort();
1232 	        }
1233 	
1234 	      /* delete all dead threads */
1235 	      for (i = 0; i < ptrace_pairs_count; i++) {
1236 	        if ((!is_alive(ptrace_pairs[i].superior) || !is_alive(ptrace_pairs[i].inferior))
1237 	                   &&
1238 	            (ptrace_pairs[i].eligible_for_deletion == TRUE)) {
1239 	          if ( i != (ptrace_pairs_count - 1)) {
1240 	            temp = ptrace_pairs[i];
1241 	            ptrace_pairs[i] = ptrace_pairs[ptrace_pairs_count - 1];
1242 	            ptrace_pairs[ptrace_pairs_count - 1] = temp;
1243 	            reset_ptrace_pairs_entry (ptrace_pairs_count - 1);
1244 	            i--;
1245 	            ptrace_pairs_count --;
1246 	          }
1247 	          else {
1248 	            reset_ptrace_pairs_entry (ptrace_pairs_count - 1);
1249 	            ptrace_pairs_count --;
1250 	            break;
1251 	          }
1252 	        }
1253 	      }
1254 	
1255 	      /* none of the eligible for deletion entries can be deleted anymore */
1256 	      for (i = 0; i < ptrace_pairs_count; i++) {
1257 	        /* SHOULDN'T "=" BE REPLACED BY "==" IN IF CONDITION?  - Gene */
Event assign_where_compare_meant: use of "=" where "==" may have been intended
Event caretline: ^
1258 	        if (ptrace_pairs[i].eligible_for_deletion = TRUE)
1259 	          ptrace_pairs[i].eligible_for_deletion = FALSE;
1260 	      }
1261 	    }
1262 	    else mtcp_printf("process_ptrace_info: NO ptrace file\n");
1263 	
1264 	    // read the information from the setoptions file
1265 	    setoptions_fd = open(ptrace_setoptions_file, O_RDONLY);
1266 	    if (setoptions_fd != -1) {
1267 	      *has_setoptions_file = 1;
1268 	      while (readall(setoptions_fd, &superior, sizeof(pid_t)) > 0) {
1269 	        readall(setoptions_fd, &inferior, sizeof(pid_t));
1270 	        if (inferior == GETTID()) {
1271 	          setoptions_superior = superior;
1272 	          is_ptrace_setoptions = TRUE;
1273 	        }
1274 	        if (*delete_setoptions_leader < superior)
1275 	          *delete_setoptions_leader = superior;
1276 	      }
1277 	        if ( close(setoptions_fd) != 0 ) {
1278 	        mtcp_printf("process_ptrace_info: Error closing file: %s\n", strerror(errno));
1279 	        mtcp_abort();
1280 	        }
1281 	    }
1282 	    else mtcp_printf ("process_ptrace_info: NO setoptions file\n");
1283 	
1284 	    // read the information from the checkpoint threads file  
1285 	    /* GDB specific code */
1286 	    checkpoint_fd = open(checkpoint_threads_file, O_RDONLY);
1287 	    if (checkpoint_fd != -1) {
1288 	      *has_checkpoint_file = 1;
1289 	      while (readall(checkpoint_fd, &pid, sizeof(pid_t)) >  0) {
1290 	        readall(checkpoint_fd, &tid, sizeof(pid_t));
1291 	        DPRINTF(("{%d} checkpoint threads: pid = %d tid = %d\n", GETTID(), pid, tid));
1292 	        if (is_alive(pid) && is_alive(tid)) {
1293 	           /* only the pid matters 
1294 	            * for the first alive tid & pid, then tid is the ckpt of pid 
1295 	            */
1296 	          if (!is_in_ckpt_threads(pid)) {
1297 	            ckpt_thread_temp.pid = pid;
1298 	            ckpt_thread_temp.tid = tid;
1299 	            ckpt_threads[ckpt_threads_count] = ckpt_thread_temp;
1300 	            ckpt_threads_count++;
1301 	          }
1302 	          if (*delete_checkpoint_leader < pid)
1303 	            *delete_checkpoint_leader = pid;
1304 	        }
1305 	      }
1306 	        if ( close(checkpoint_fd) != 0 ) {
1307 	        mtcp_printf("process_ptrace_info: Error closing file: %s\n", strerror(errno));
1308 	        mtcp_abort();
1309 	        }
1310 	    }
1311 	    else mtcp_printf("process_ptrace_info: NO checkpoint file\n");
1312 	
1313 	    sort_ptrace_pairs ();
1314 	
1315 	    print_ptrace_pairs ();
1316 	
1317 	    print_ckpt_threads ();
1318 	
1319 	    // We dont need sem_post anymore because this function is only called by checkpoint thread
1320 	    // TODO: remove semaphor-related stuff
1321 	
1322 	    /* allow all other threads to proceed 
1323 	     * for all the threads excluding motherofall and checkpoint thread */
1324 	/*     
1325 	    for (loopthread = threads; loopthread != NULL && loopthread->next != NULL && loopthread->next->next != NULL;
1326 	                  loopthread = loopthread->next) { 
1327 	      sem_post(&ptrace_read_pairs_sem);
1328 	
1329 	    }
1330 	  }else 
1331 	    // all threads with the exception of motherofall (checkpoint thread does NOT run this code) wait for motherofall to write
1332 	    //   the info from the ptrace file to memory (shared among all threads of a process) 
1333 	    sem_wait(&ptrace_read_pairs_sem); 
1334 	*/
1335 	
1336 	}
1337 	
1338 	static int is_checkpoint_thread (pid_t tid)
1339 	{
1340 	  int i;
1341 	  for (i = 0; i < ckpt_threads_count; i++) {
1342 	    if (ckpt_threads[i].tid == tid ) return ckpt_threads[i].pid;
1343 	  }
1344 	  return 0;
1345 	}
1346 	
1347 	static int ptrace_detach_ckpthread(pid_t tgid, pid_t tid, pid_t supid)
1348 	{
1349 	  int status;
1350 	  char pstate;
1351 	  pid_t tpid;
1352 	
1353 	  DPRINTF(("detach_ckpthread: tid=%d, tgid = %d >>>>>>>>>>>>>>>>>>\n", tid, tgid));
1354 	
1355 	  pstate = procfs_state(tid);
1356 	  DPRINTF(("detach_ckpthread: CKPT Thread procfs_state(%d) = %c\n", tid, pstate));
1357 	  if( pstate == 0 ){
1358 	  // such process not exist 
1359 	    return -ENOENT;
1360 	  }else if (pstate == 'T') {
1361 	    // There can be posibility that GDB (or other) reads status of this
1362 	    // thread before us. So we will block. We don't want that.    // Read anyway but without hang
1363 	    DPRINTF(("detach_ckpthread: Checkpoint thread already stopped\n"));
1364 	
1365 	    is_waitpid_local = 1;
1366 	    tpid = waitpid(tid, &status, WNOHANG);
1367 	    if (tpid == -1 && errno == ECHILD) {
1368 	      DPRINTF(("detach_ckpthread: Check cloned process\n"));
1369 	      // Try again with __WCLONE to check cloned processes.
1370 	      is_waitpid_local = 1;
1371 	      if ((tpid = waitpid(tid, &status, __WCLONE | WNOHANG)) == -1) {
1372 	        DPRINTF(("detach_ckpthread: ptrace_detach_checkpoint_threads: waitpid(..,__WCLONE): %s\n"
1373 	,
1374 	                    strerror(errno)));
1375 	      }
1376 	    }
1377 	    DPRINTF(("detach_ckpthread: tgid = %d, tpid=%d,stopped=%d is_sigstop=%d,signal=%d\n",
1378 	             tid, tpid, WIFSTOPPED(status),
1379 	             WSTOPSIG(status) == SIGSTOP, WSTOPSIG(status)));
1380 	  }else{
1381 	    /*
1382 	     * and if inferior is a checkpoint thread 
1383 	     */
1384 	    if (kill(tid, SIGSTOP) == -1) {
1385 	      mtcp_printf("detach_ckpthread: ptrace_detach_checkpoint_threads: kill: %s\n",
1386 	                  strerror(errno));
1387 	      return -EAGAIN;
1388 	    }
1389 	    is_waitpid_local = 1;
1390 	    tpid = waitpid(tid, &status, 0);
1391 	    DPRINTF(("detach_ckpthread: tpid1=%d,errno=%d,ECHILD=%d\n", tpid, errno, ECHILD));
1392 	    if ((tpid) == -1 && errno == ECHILD) {
1393 	      DPRINTF(("detach_ckpthread: Check cloned process\n"));
1394 	      /*
1395 	       * Try again with __WCLONE to check cloned processes.  
1396 	       */
1397 	      is_waitpid_local = 1;
1398 	      if ((tpid = waitpid(tid, &status, __WCLONE)) == -1) {
1399 	        mtcp_printf("detach_ckpthread: ptrace_detach_checkpoint_threads: waitpid(..,__WCLONE): %s\n",
1400 	                    strerror(errno));
1401 	        return -EAGAIN;
1402 	      }
1403 	    }
1404 	  }
1405 	  DPRINTF(("detach_ckpthread: tgid = %d, tpid=%d,stopped=%d is_sigstop=%d,"
1406 	           "signal=%d,err=%s\n",
1407 	           tid, tpid, WIFSTOPPED(status),WSTOPSIG(status) == SIGSTOP,
1408 	           WSTOPSIG(status), strerror(errno)));
1409 	  if (WIFSTOPPED(status)) {
1410 	    if (WSTOPSIG(status) == SIGSTOP)
1411 	      DPRINTF(("detach_ckpthread: checkpoint thread %d was stopped by the delivery of SIGSTOP\n",tid));
1412 	    else {                      // we should never get here 
1413 	      DPRINTF(("detach_ckpthread: checkpoint thread %d was stopped by the delivery of %d\n",
1414 	               tid,WSTOPSIG(status)));
1415 	    }
1416 	  } else                        // we should never end up here 
1417 	    DPRINTF(("detach_ckpthread: checkpoint thread %d was NOT stopped by a signal\n", tid));
1418 	
1419 	  is_ptrace_local = 1;
1420 	  if (ptrace(PTRACE_DETACH, tid, 0, SIGCONT) == -1) {
1421 	    DPRINTF(("detach_ckpthread: ptrace_detach_checkpoint_threads: parent = %d child = %d\n",
1422 	             supid, tid));
1423 	    DPRINTF(("detach_ckpthread: ptrace_detach_checkpoint_threads: PTRACE_DETACH failed: %s\n",
1424 	             strerror(errno)));
1425 	    return -EAGAIN;
1426 	  }
1427 	
1428 	  DPRINTF(("detach_ckpthread: tid=%d, tgid = %d <<<<<<<<<<<<<<<<<<<<<<<<<<\n", tid, tgid));
1429 	  only_once = 0; /* no need for semaphore here - the UT execute this code */
1430 	  return 0;
1431 	}
1432 	
1433 	static int ptrace_control_ckpthread(pid_t tgid, pid_t tid)
1434 	{
1435 	  int status;
1436 	  char pstate;
1437 	  pid_t tpid;
1438 	
1439 	  DPRINTF(("control_ckpthread: tid=%d, tgid = %d >>>>>>>>>>>>>>>>>>>>>>>\n", tid, tgid));
1440 	
1441 	  pstate = procfs_state(tid);
1442 	  DPRINTF(("control_ckpthread: CKPT Thread procfs_state(%d) = %c\n", tid, pstate));
1443 	
1444 	  if( pstate == 0 ){
1445 	    // process not exist
1446 	    return -ENOENT;
1447 	  }else if( pstate == 'T') {
1448 	    // There can be posibility that GDB (or other) reads status of this
1449 	    // thread before us. So we will block. We don't want that.
1450 	    // Read anyway but without hang
1451 	    DPRINTF(("control_ckpthread: Checkpoint thread stopped by controlled debugger\n"));
1452 	
1453 	    if( mtcp_sys_kernel_tkill(tid,SIGCONT) )
1454 	      return -EAGAIN;
1455 	
1456 	    DPRINTF(("control_ckpthread: Check cloned process\n"));
1457 	    // Try again with __WCLONE to check cloned processes.
1458 	    is_waitpid_local = 1;
1459 	    if ((tpid = waitpid(tid, &status, __WCLONE | WNOHANG)) == -1) {
1460 	      mtcp_printf("control_ckpthread: ptrace_detach_checkpoint_threads: waitpid(..,__WCLONE): %s\n",
1461 	                  strerror(errno));
1462 	      return -EAGAIN;
1463 	    }
1464 	
1465 	    DPRINTF(("control_ckpthread: tgid = %d, tpid=%d,continued=%d,err=%s\n",
1466 	       tid, tpid, WIFCONTINUED(status), strerror(errno)));
1467 	
1468 	    if( WIFCONTINUED(status) ) {
1469 	      DPRINTF(("control_ckpthread: checkpoint thread %d was stopped by the delivery of SIGSTOP\n",tid));
1470 	    }else{                        // we should never end up here 
1471 	      DPRINTF(("control_ckpthread: checkpoint thread %d was NOT stopped by a signal\n", tid));
1472 	    }
1473 	  }
1474 	
1475 	  DPRINTF(("control_ckpthread: tid=%d, tgid = %d <<<<<<<<<<<<<<<<<<<<<<<<<<\n", tid, tgid));
1476 	  return 0;
1477 	}
1478 	
1479 	void ptrace_save_threads_state ()
1480 	{
1481 	  int i;
1482 	
1483 	  DPRINTF((">>>>>>>>> start ptrace_save_threads_state %d\n", GETTID()));
1484 	
1485 	  for(i = 0; i < ptrace_pairs_count; i++) {
1486 	  /*
1487 	    if( is_checkpoint_thread(ptrace_pairs[i].inferior) ){
1488 	      mtcp_printf("ptrace_detach_user_threads: SKIP checkpoint thread %d\n",ptrace_pairs[i].inferior);
1489 	      continue;
1490 	    }
1491 	  */
1492 	    //if( ptrace_pairs[i].superior == GETTID()){
1493 	      char pstate;
1494 	      int tid = ptrace_pairs[i].inferior;
1495 	      pstate = procfs_state(tid);
1496 	      DPRINTF(("save state of thread %d = %c\n",tid,pstate));
1497 	      ptrace_pairs[i].inferior_st = pstate;
1498 	    //}     
1499 	  }
1500 	  DPRINTF((">>>>>>>>> done ptrace_save_threads_state %d\n", GETTID()));
1501 	}
1502 	
1503 	#endif