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);
Event secure_coding: [VERY RISKY]. Using "sprintf" can cause a buffer overflow when done incorrectly. Because sprintf() assumes an arbitrarily long string, callers must be careful not to overflow the actual space of the destination. Use snprintf() instead, or correct precision specifiers.
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 */
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