merge checkpoint
[dyninst.git] / stackwalk / src / linux-swk.C
1 /*
2  * Copyright (c) 1996-2007 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
30  */
31
32 #include "stackwalk/h/swk_errors.h"
33 #include "stackwalk/h/symlookup.h"
34 #include "stackwalk/h/walker.h"
35 #include "stackwalk/h/steppergroup.h"
36
37 #include "stackwalk/h/procstate.h"
38 #include "stackwalk/src/linux-swk.h"
39 #include "stackwalk/src/symtab-swk.h"
40
41 #include "common/h/linuxKludges.h"
42 #include "common/h/parseauxv.h"
43
44 #include <string>
45 #include <sstream>
46
47 #include <string.h>
48 #include <sys/syscall.h>
49 #include <unistd.h>
50 #include <errno.h>
51 #include <assert.h>
52 #include <signal.h>
53 #include <sys/types.h>
54 #include <sys/wait.h>
55 #include <sys/mman.h>
56 #include <fcntl.h>
57
58 using namespace Dyninst;
59 using namespace Dyninst::Stackwalker;
60
61 #ifndef SYS_tkill
62 #define SYS_tkill 238
63 #endif
64
65 //These should be defined on all modern linux's, turn these off
66 // if porting to some linux-like platform that doesn't support 
67 // them.
68 #include <sys/ptrace.h>
69 #include <linux/ptrace.h>
70 typedef enum __ptrace_request pt_req;
71 #define cap_ptrace_traceclone
72 #define cap_ptrace_setoptions
73
74 ProcDebug::thread_map_t ProcDebugLinux::all_threads;
75
76 static int P_gettid()
77 {
78   static int gettid_not_valid = 0;
79   long int result;
80
81   if (gettid_not_valid)
82     return getpid();
83
84   result = syscall(SYS_gettid);
85   if (result == -1 && errno == ENOSYS)
86   {
87     gettid_not_valid = 1;
88     return getpid();
89   }
90   return (int) result;
91 }
92
93 static bool t_kill(int pid, int sig)
94 {
95   static bool has_tkill = true;
96   long int result = 0;
97   sw_printf("[%s:%u] - Sending %d to %d\n", __FILE__, __LINE__, sig, pid);
98   if (has_tkill) {
99      result = syscall(SYS_tkill, pid, sig);
100      if (result == -1 && errno == ENOSYS)
101      {
102         sw_printf("[%s:%d] - Using kill instead of tkill on this system\n", 
103                   __FILE__, __LINE__, sig, pid);
104         has_tkill = false;
105      }
106   }
107   if (!has_tkill) {
108      result = kill(pid, sig);
109   }
110
111   return (result == 0);
112 }
113
114 static void registerLibSpotterSelf(ProcSelf *pself);
115 ProcSelf::ProcSelf() :
116    ProcessState(getpid())
117 {
118 }
119
120 void ProcSelf::initialize()
121 {
122 #if defined(cap_stackwalker_use_symtab)
123    library_tracker = new SymtabLibState(this);
124 #else
125    library_tracker = new DefaultLibState(this);
126 #endif
127    assert(library_tracker);
128    registerLibSpotterSelf(this);
129 }
130
131 #if defined(cap_sw_catchfaults)
132
133 #include <setjmp.h>
134
135 static bool registered_handler = false;
136 static bool reading_memory = false;
137 sigjmp_buf readmem_jmp;
138
139 void handle_fault(int /*sig*/)
140 {
141    if (!reading_memory) {
142       //The instruction that caused this fault was not from
143       // ProcSelf::readMem.  Restore the SIGSEGV handler, and 
144       // the faulting instruction should restart after we return.
145       fprintf(stderr, "[%s:%u] - Caught segfault that didn't come " \
146               "from stackwalker memory read!", __FILE__, __LINE__);
147       signal(SIGSEGV, SIG_DFL);
148       return;
149    }
150    siglongjmp(readmem_jmp, 1);
151 }
152
153 bool ProcSelf::readMem(void *dest, Address source, size_t size)
154 {
155    if (!registered_handler) {
156       signal(SIGSEGV, handle_fault);
157       registered_handler = true;
158    }
159    reading_memory = true;
160    if (sigsetjmp(readmem_jmp, 1)) {
161       sw_printf("[%s:%u] - Caught fault while reading from %lx to %lx\n", 
162                 __FILE__, __LINE__, source, source + size);
163       setLastError(err_procread, "Could not read from process");
164       return false;
165    }
166    
167    memcpy(dest, (const void *) source, size);
168    reading_memory = false;
169    return true;
170 }
171 #else
172 bool ProcSelf::readMem(void *dest, Address source, size_t size)
173 {
174   memcpy(dest, (const void *) source, size);
175   return true;
176 }
177 #endif
178
179 bool ProcSelf::getThreadIds(std::vector<THR_ID> &threads)
180 {
181   bool result;
182   THR_ID tid;
183
184   result = getDefaultThread(tid);
185   if (!result) {
186     sw_printf("[%s:%u] - Could not read default thread\n",
187                __FILE__, __LINE__);
188     return false;
189   }
190   threads.clear();
191   threads.push_back(tid);
192   return true;
193 }
194
195 bool ProcDebugLinux::isLibraryTrap(Dyninst::THR_ID thrd)
196 {
197    LibraryState *ls = getLibraryTracker();
198    if (!ls)
199       return false;
200    Address lib_trap_addr = ls->getLibTrapAddress();
201    if (!lib_trap_addr)
202       return false;
203
204    Dyninst::MachRegisterVal cur_pc;
205    bool result = getRegValue(Dyninst::MachRegPC, thrd, cur_pc);
206    if (!result) {
207       sw_printf("[%s:%u] - Error getting PC value for thrd %d\n",
208                 __FILE__, __LINE__, (int) thrd);
209       return false;
210    }
211    if (cur_pc == lib_trap_addr || cur_pc-1 == lib_trap_addr)
212       return true;
213    return false;
214 }
215
216
217 bool ProcSelf::getDefaultThread(THR_ID &default_tid)
218 {
219   THR_ID tid = P_gettid();
220   if (tid == -1) {
221     const char *sys_err_msg = strerror(errno);
222     sw_printf("[%s:%u] - gettid syscall failed with %s\n",
223                __FILE__, __LINE__, sys_err_msg);
224     std::string errmsg("gettid syscall failed with ");
225     errmsg += sys_err_msg;
226     setLastError(err_internal, errmsg.c_str());
227     return false;
228   }
229
230   default_tid = tid;
231   return true;
232 }
233
234 DebugEvent ProcDebug::debug_get_event(bool block)
235 {
236    int status = 0;
237    DebugEvent ev;
238    pid_t p;
239
240    int flags = __WALL;
241    if (!block)
242      flags |= WNOHANG;
243    sw_printf("[%s:%u] - Calling waitpid(-1, %p, %d)\n",
244              __FILE__, __LINE__, &status, flags);
245    p = waitpid(-1, &status, flags);
246    sw_printf("[%s:%u] - waitpid returned status = 0x%x, p = %d\n",
247              __FILE__, __LINE__, status, p);
248    if (p == -1) {
249       int errnum = errno;
250       sw_printf("[%s:%u] - Unable to wait for debug event: %s\n",
251                 __FILE__, __LINE__, strerror(errnum));
252       if (errnum == EINTR)
253          setLastError(err_interrupt, "System call interrupted");
254       else
255          setLastError(err_internal, "Error calling waitpid");
256       ev.dbg = dbg_err;
257       return ev;
258    }
259    
260    if (p == 0) {
261      sw_printf("[%s:%u] - No debug events available\n", __FILE__, __LINE__);
262      ev.dbg = dbg_noevent;
263      return ev;
264    }
265
266    if (pipe_out != -1)
267    {
268       /*struct pollfd[1];
269       pollfd[0].fd = pipe_out;
270       pollfd[0].events = POLLIN;
271       pollfd[0].revents = 0;
272       poll(pollfd, 1, 0);*/
273       char c;
274       read(pipe_out, &c, 1);
275    }
276
277    thread_map_t::iterator i = ProcDebugLinux::all_threads.find(p);
278    if (i == ProcDebugLinux::all_threads.end())
279    {
280       sw_printf("[%s:%u] - Error, recieved unknown pid %d from waitpid",
281                 __FILE__, __LINE__, p);
282       setLastError(err_internal, "Error calling waitpid");
283       ev.dbg = dbg_err;
284       return ev;
285    }
286    
287    ev.thr = i->second;
288    ev.proc = ev.thr->proc();
289
290    if (WIFEXITED(status)) 
291    {
292       ev.dbg = dbg_exited;
293       ev.data.idata = WEXITSTATUS(status);
294       sw_printf("[%s:%u] - Process %d exited with %d\n", 
295                 __FILE__, __LINE__, p, ev.dbg);
296    }
297    else if (WIFSIGNALED(status))
298    {
299       ev.dbg = dbg_crashed;
300       ev.data.idata = WTERMSIG(status);
301       sw_printf("[%s:%u] - Process %d crashed with %d\n", 
302                 __FILE__, __LINE__, p, ev.dbg);
303    }
304    else if (WIFSTOPPED(status))
305    {
306       ev.dbg = dbg_stopped;
307       ev.data.idata = WSTOPSIG(status);
308       
309       ProcDebugLinux *linux_proc = dynamic_cast<ProcDebugLinux*>(ev.proc);
310       assert(linux_proc);
311       if (ev.data.idata == SIGTRAP) {
312          if (linux_proc->state() == ps_running && 
313              linux_proc->isLibraryTrap((Dyninst::THR_ID) p)) 
314          {
315             sw_printf("[%s:%u] - Decoded library load event\n",
316                       __FILE__, __LINE__);
317             ev.dbg = dbg_libraryload;
318          }
319          else {
320             int extended_data = status >> 16;
321             if (extended_data)
322                ev.data.idata = (extended_data << 8) | SIGTRAP;
323          }
324       }
325       sw_printf("[%s:%u] - Process %d stopped with %d\n",
326                 __FILE__, __LINE__, p, ev.data);
327    }
328    else
329    {
330       sw_printf("[%s:%u] - Process %d had strange return value from waitpid\n",
331                 __FILE__, __LINE__, p);
332       setLastError(err_internal, "Error calling waitpid");
333       ev.dbg = dbg_err;
334    }
335    return ev;
336 }
337
338 bool ProcDebugLinux::debug_handle_event(DebugEvent ev)
339 {
340   bool result;
341   ThreadState *thr = ev.thr;
342
343   switch (ev.dbg)
344   {
345      case dbg_stopped:
346         thr->setStopped(true);
347         if (thr->state() == ps_attached_intermediate && 
348             (ev.data.idata == SIGSTOP || ev.data.idata == SIGTRAP)) {
349            sw_printf("[%s:%u] - Moving %d/%d to state running\n", 
350                      __FILE__, __LINE__, pid, thr->getTid());
351            thr->setState(ps_running);
352            return true;
353         }
354
355 #if defined(cap_ptrace_traceclone)
356         if (ev.data.idata == (SIGTRAP | (PTRACE_EVENT_CLONE << 8))) {
357            sw_printf("[%s:%u] - Discovered new thread in proc %d\n", 
358                      __FILE__, __LINE__, pid);
359            pid_t newtid;
360            ThreadState *new_thread = NULL;
361            long iresult = ptrace((pt_req) PTRACE_GETEVENTMSG, thr->getTid(), 
362                                  NULL, &newtid);
363            if (iresult == -1) {
364               sw_printf("[%s:%u] - Unexpected error getting new tid on %d\n"
365                      __FILE__, __LINE__, pid);
366            }
367            else 
368            {
369               sw_printf("[%s:%u] - New thread %ld in proc %d\n",
370                         __FILE__, __LINE__, newtid, pid);
371               new_thread = ThreadState::createThreadState(this, (THR_ID) newtid, true);
372            }
373            if (!new_thread) {
374               sw_printf("[%s:%u] - Error creating thread %d in proc %d\n",
375                         __FILE__, __LINE__, newtid, pid);
376            }
377            result = debug_continue(thr);
378            if (!result) {
379               sw_printf("[%s:%u] - Debug continue failed on %d/%d\n",
380                         __FILE__, __LINE__, pid, thr->getTid());
381               return false;
382            }
383            return true;
384         }
385 #endif
386         
387         if (ev.data.idata != SIGSTOP) {
388            result = debug_continue_with(thr, ev.data.idata);
389            if (!result) {
390               sw_printf("[%s:%u] - Debug continue failed on %d/%d with %d\n", 
391                         __FILE__, __LINE__, pid, thr->getTid(), ev.data.idata);
392               return false;
393            }
394         }
395         return true;
396     case dbg_libraryload: 
397     {
398        sw_printf("[%s:%u] - Handling library load event on %d/%d\n",
399                  __FILE__, __LINE__, pid, thr->getTid());
400        thr->setStopped(true);
401        LibraryState *ls = getLibraryTracker();
402        assert(ls);
403        ls->notifyOfUpdate();
404        
405        result = debug_continue_with(thr, 0);
406        if (!result) {
407           sw_printf("[%s:%u] - Debug continue failed on %d/%d with %d\n", 
408                     __FILE__, __LINE__, pid, thr->getTid(), ev.data.idata);
409           return false;
410        }
411        return true;
412     }
413     case dbg_crashed:
414       sw_printf("[%s:%u] - Handling process crash on %d/%d\n",
415                 __FILE__, __LINE__, pid, thr->getTid());
416     case dbg_exited:
417       sw_printf("[%s:%u] - Handling process death on %d/%d\n",
418                 __FILE__, __LINE__, pid, thr->getTid());
419       thr->setState(ps_exited);
420       return true;
421     case dbg_err:
422     case dbg_noevent:
423     default:
424       sw_printf("[%s:%u] - Unexpectedly handling an error event %d on %d/%d\n", 
425                 __FILE__, __LINE__, ev.dbg, pid, thr->getTid());
426       setLastError(err_internal, "Told to handle an unexpected event.");
427       return false;
428   }
429 }
430
431 bool ProcDebugLinux::debug_handle_signal(DebugEvent *ev)
432 {
433    assert(ev->dbg == dbg_stopped);
434    return debug_continue_with(ev->thr, ev->data.idata);
435 }
436
437 #if defined(cap_ptrace_setoptions)   
438 void ProcDebugLinux::setOptions(Dyninst::THR_ID tid)
439 {
440
441    long options = 0;
442 #if defined(cap_ptrace_traceclone)
443    options |= PTRACE_O_TRACECLONE;
444 #endif
445
446    if (options) {
447       int result = ptrace((pt_req) PTRACE_SETOPTIONS, tid, NULL, 
448                           (void *) options);
449       if (result == -1) {
450          sw_printf("[%s:%u] - Failed to set options for %d: %s\n", 
451                    __FILE__, __LINE__, tid, strerror(errno));
452       }
453    }   
454 }
455 #else
456 void ProcDebugLinux::setOptions(Dyninst::THR_ID)
457 {
458 }
459 #endif
460
461 bool ProcDebugLinux::debug_attach(ThreadState *ts)
462 {
463    long result;
464    pid_t tid = (pid_t) ts->getTid();
465    
466    sw_printf("[%s:%u] - Attaching to pid %d\n", __FILE__, __LINE__, tid);
467    result = ptrace((pt_req) PTRACE_ATTACH, tid, NULL, NULL);
468    if (result != 0) {
469       int errnum = errno;
470       sw_printf("[%s:%u] - Unable to attach to process %d: %s\n",
471                 __FILE__, __LINE__, tid, strerror(errnum));
472       if (errnum == EPERM)
473          setLastError(err_prem, "Do not have correct premissions to attach " \
474                       "to pid");
475       else if (errnum == ESRCH)
476          setLastError(err_noproc, "The specified process was not found");
477       else {
478          setLastError(err_internal, "DynStackwalker was unable to attach to " \
479                       "the specified process");
480       }
481       return false;
482    }
483    ts->setState(ps_attached_intermediate);   
484
485    return true;
486 }
487
488 bool ProcDebugLinux::debug_post_create()
489 {
490    sw_printf("[%s:%u] - Post create on %d\n", __FILE__, __LINE__, pid);
491    setOptions(pid);
492
493 #if defined(cap_stackwalker_use_symtab)
494    library_tracker = new SymtabLibState(this);
495 #else
496    library_tracker = new DefaultLibState(this);
497 #endif
498    assert(library_tracker);
499    registerLibSpotter();
500    return true;
501 }
502
503 bool ProcDebugLinux::debug_post_attach(ThreadState *thr)
504 {
505    sw_printf("[%s:%u] - Post attach on %d\n", __FILE__, __LINE__, thr->getTid());
506    THR_ID tid = thr->getTid();
507    setOptions(tid);
508
509 #if defined(cap_stackwalker_use_symtab)
510    library_tracker = new SymtabLibState(this);
511 #else
512    library_tracker = new DefaultLibState(this);
513 #endif   
514    assert(library_tracker);
515    registerLibSpotter();
516
517    if (tid == pid) {
518       //We're attach to the initial process, also attach to all threads
519       pollForNewThreads();
520    }
521    return true;
522 }
523
524 bool ProcDebugLinux::debug_pause(ThreadState *thr)
525 {
526    bool result;
527
528    result = t_kill(thr->getTid(), SIGSTOP);
529    if (!result) {
530       if (errno == ESRCH) {
531          sw_printf("[%s:%u] - t_kill failed on %d, thread doesn't exist\n",
532                    __FILE__, __LINE__, thr->getTid());
533          setLastError(err_noproc, "Thread no longer exists");
534          return false;
535       }
536       sw_printf("[%s:%u] - t_kill failed on %d: %s\n", __FILE__, __LINE__,
537                 thr->getTid(), strerror(errno));
538       setLastError(err_internal, "Could not send signal to process while " \
539                    "stopping");
540       return false;
541    }
542    
543    return true;
544 }
545
546 bool ProcDebugLinux::debug_continue(ThreadState *thr)
547 {
548    return debug_continue_with(thr, 0);
549 }
550
551 bool ProcDebugLinux::debug_continue_with(ThreadState *thr, long sig)
552 {
553    long result;
554    assert(thr->isStopped());
555    Dyninst::THR_ID tid = thr->getTid();
556    sw_printf("[%s:%u] - Calling PTRACE_CONT with signal %d on %d\n",
557              __FILE__, __LINE__, sig, tid);
558    result = ptrace((pt_req) PTRACE_CONT, tid, NULL, (void *) sig);
559    if (result != 0)
560    {
561      int errnum = errno;
562       sw_printf("[%s:%u] - Error continuing %d with %d: %s\n",
563                 __FILE__, __LINE__, tid, sig, strerror(errnum));
564       setLastError(err_internal, "Could not continue process");
565       return false;
566    }
567
568    thr->setStopped(false);
569    return true;
570 }
571
572 bool ProcDebugLinux::readMem(void *dest, Address source, size_t size)
573 {
574    unsigned long nbytes = size;
575    const unsigned char *ap = (const unsigned char*) source;
576    unsigned char *dp = (unsigned char*) dest;
577    Address w = 0x0;               /* ptrace I/O buffer */
578    int len = sizeof(long);
579    unsigned long cnt;
580    
581    if (!nbytes) {
582       return true;
583    }
584    
585    ThreadState *thr = active_thread;
586    if (!thr) {
587       //Likely doing this read in response to some event, perhaps
588       // without an active thread.  The event should have stopped something,
589       // so find a stopped thread.
590       thread_map_t::iterator i;
591       for (i = threads.begin(); i != threads.end(); i++) {
592          ThreadState *t = (*i).second;
593          if (t->state() == ps_exited)
594             continue;
595          if (t->isStopped()) {
596             thr = t;
597             break;
598          }
599       }
600    }
601    assert(thr); //Something should be stopped if we're here.
602    pid_t tid = (pid_t) thr->getTid();
603
604    if ((cnt = ((Address)ap) % len)) {
605       /* Start of request is not aligned. */
606       unsigned char *p = (unsigned char*) &w;
607       
608       /* Read the segment containing the unaligned portion, and
609          copy what was requested to DP. */
610       errno = 0;
611       w = ptrace((pt_req) PTRACE_PEEKTEXT, tid, (Address) (ap-cnt), w);
612       if (errno) {
613          int errnum = errno;
614          sw_printf("[%s:%u] - PTRACE_PEEKTEXT returned error on %d: %s\n",
615                    __FILE__, __LINE__, pid, strerror(errnum));
616          setLastError(err_procread, "Could not read from process\n");
617          return false;
618       }
619
620       for (unsigned i = 0; i < len-cnt && i < nbytes; i++)
621          dp[i] = p[cnt+i];
622       
623       if (len-cnt >= nbytes) {
624          return true;
625       }
626       
627       dp += len-cnt;
628       ap += len-cnt;
629       nbytes -= len-cnt;
630    }
631    /* Copy aligned portion */
632    while (nbytes >= (u_int)len) {
633       errno = 0;
634       w = ptrace((pt_req) PTRACE_PEEKTEXT, tid, (Address) ap, 0);
635       if (errno) {
636          int errnum = errno;
637          sw_printf("[%s:%u] - PTRACE_PEEKTEXT returned error on %d: %s\n",
638                    __FILE__, __LINE__, pid, strerror(errnum));
639          setLastError(err_procread, "Could not read from process\n");
640          return false;
641       }
642       memcpy(dp, &w, len);
643       dp += len;
644       ap += len;
645       nbytes -= len;
646    }
647    
648    if (nbytes > 0) {
649       /* Some unaligned data remains */
650       unsigned char *p = (unsigned char *) &w;
651       
652       /* Read the segment containing the unaligned portion, and
653          copy what was requested to DP. */
654       errno = 0;
655       w = ptrace((pt_req) PTRACE_PEEKTEXT, tid, (Address) ap, 0);
656       if (errno) {
657          int errnum = errno;
658          sw_printf("[%s:%u] - PTRACE_PEEKTEXT returned error on %d: %s\n",
659                    __FILE__, __LINE__, pid, strerror(errnum));
660          setLastError(err_procread, "Could not read from process\n");
661          return false;
662       }
663       for (unsigned i = 0; i < nbytes; i++)
664          dp[i] = p[i];
665    }
666
667    return true;
668 }   
669
670 bool ProcDebugLinux::getThreadIds(std::vector<THR_ID> &thrds)
671 {
672 #if !defined(cap_ptrace_traceclone)
673    pollForNewThreads();
674 #endif
675    thread_map_t::iterator i;
676    for (i = threads.begin(); i != threads.end(); i++) {
677       ThreadState *ts = (*i).second;
678       if (ts->state() != ps_running)
679          continue;
680       thrds.push_back(ts->getTid());
681    }
682    return true;
683 }
684
685 bool ProcDebugLinux::pollForNewThreads()
686 {
687    std::vector<THR_ID> thrds;
688    bool result = findProcLWPs(pid, thrds);
689    if (!result) {
690       sw_printf("[%s:%u] - getThreadIds failed in libcommon's findProcLWPs "
691                 "for %d", __FILE__, __LINE__, pid);                
692       return false;
693    }
694    
695    bool had_error = false;
696    std::vector<THR_ID>::iterator i;
697    for (i=thrds.begin(); i != thrds.end(); i++) {
698       if (threads.count(*i)) {
699          continue;
700       }
701       sw_printf("[%s:%u] - Discovered unknown thread %d, in proc %d\n",
702                 __FILE__, __LINE__, *i, pid);
703       ThreadState *new_thread = ThreadState::createThreadState(this, *i);
704       if (!new_thread && getLastError() == err_noproc) {
705          //Race condition, get thread ID or running thread, which then 
706          // exits.  Should be rare...
707          sw_printf("[%s:%u] - Error creating thread %d, does not exist\n",
708                    __FILE__, __LINE__, *i);
709          clearLastError();
710          continue;
711       }
712       else if (!new_thread) {
713          sw_printf("[%s:%u] - Unexpected error creating thread %d\n",
714                    __FILE__, __LINE__, *i);
715          had_error = true;
716          continue;
717       }
718    }
719    return had_error;
720 }
721
722 bool ProcDebugLinux::getDefaultThread(THR_ID &default_tid)
723 {
724    default_tid = (THR_ID) pid;
725    return true;
726 }
727
728 ProcDebugLinux::ProcDebugLinux(PID pid)
729    : ProcDebug(pid),
730      cached_addr_width(0)
731 {
732 }
733
734 ProcDebugLinux::ProcDebugLinux(const std::string &executable, 
735                                const std::vector<std::string> &argv)
736    : ProcDebug(executable, argv),
737      cached_addr_width(0)
738 {
739 }
740
741 ProcDebugLinux::~ProcDebugLinux()
742 {
743 }
744    
745 ProcDebug *ProcDebug::newProcDebug(PID pid)
746 {
747    ProcDebugLinux *pd = new ProcDebugLinux(pid);
748    if (!pd)
749    {
750       sw_printf("[%s:%u] - Error creating new ProcDebug object\n",
751                 __FILE__, __LINE__);
752       return pd;
753    }
754
755    bool result = pd->attach();
756    if (!result || pd->state() != ps_running) {
757      pd->setState(ps_errorstate);
758      proc_map.erase(pid);
759      sw_printf("[%s:%u] - Error attaching to process %d\n",
760                __FILE__, __LINE__, pid);
761      delete pd;
762      return NULL;
763    }
764
765    return pd;
766 }
767
768 ProcDebug *ProcDebug::newProcDebug(const std::string &executable, 
769                                    const std::vector<std::string> &argv)
770 {
771    ProcDebugLinux *pd = new ProcDebugLinux(executable, argv);
772    if (!pd)
773    {
774       sw_printf("[%s:%u] - Error creating new ProcDebug object\n",
775                 __FILE__, __LINE__);
776       return NULL;
777    }
778
779    bool result = pd->create(executable, argv);
780    if (!result || pd->state() != ps_running)
781    {
782      pd->setState(ps_errorstate);
783      proc_map.erase(pd->pid);
784      sw_printf("[%s:%u] - Error attaching to process %d\n",
785                __FILE__, __LINE__, pd->pid);
786      delete pd;
787      return NULL;
788    }
789
790    return pd;   
791 }
792
793
794 void chld_handler(int)
795 {
796    write(ProcDebug::pipe_in, "s", 1);
797 }
798
799 int ProcDebug::getNotificationFD()
800 {
801    static bool registered_handler = false;
802    int filedes[2], result;
803    if (!registered_handler) 
804    {
805       signal(SIGCHLD, chld_handler);
806       result = pipe(filedes);
807       if (result == -1)
808       {
809          int errnum = errno;
810          sw_printf("[%s:%u] - Could not create pipe: %s\n",
811                    __FILE__, __LINE__, strerror(errnum));
812          setLastError(err_internal, "Could not create pipe for notificationFD");
813          return -1;
814       }
815       pipe_out = filedes[0];
816       pipe_in = filedes[1];
817
818       result = fcntl(pipe_out, F_GETFL);
819       if (result != -1)
820       {
821          result = fcntl(pipe_out, F_SETFL, result | O_NONBLOCK);
822       }
823       if (result == -1)
824       {
825          int errnum = errno;
826          sw_printf("[%s:%u] - Could not set fcntl flags: %s\n",
827                    __FILE__, __LINE__, strerror(errnum));
828          setLastError(err_internal, "Could not set pipe properties");
829          return -1;
830       }
831       registered_handler = true;
832    }
833    return pipe_out;
834 }
835
836 bool ProcDebugLinux::debug_create(const std::string &executable, 
837                                   const std::vector<std::string> &argv)
838 {
839    pid = fork();
840    if (pid == -1)
841    {
842       int errnum = errno;
843       sw_printf("[%s:%u] - Could not fork new process for %s: %s\n",
844                 __FILE__, __LINE__, executable.c_str(), strerror(errnum));
845       setLastError(err_internal, "Unable to fork new process");
846       return false;
847    }
848
849    if (pid)
850    {
851    }
852    else
853    {
854       //Child
855       long int result = ptrace((pt_req) PTRACE_TRACEME, 0, 0, 0);
856       unsigned i;
857       if (result == -1)
858       {
859          sw_printf("[%s:%u] - Failed to execute a PTRACE_TRACME.  Odd.\n",
860                    __FILE__, __LINE__);
861          setLastError(err_internal, "Unable to debug trace new process");
862          exit(-1);
863       }
864
865       typedef const char * const_str;
866       
867       const_str *new_argv = (const_str *) calloc(argv.size()+3, sizeof(char *));
868       new_argv[0] = executable.c_str();
869       for (i=1; i<argv.size()+1; i++) {
870          new_argv[i] = argv[i-1].c_str();
871       }
872       new_argv[i+1] = (char *) NULL;
873       
874       result = execv(executable.c_str(), const_cast<char * const*>(new_argv));
875       int errnum = errno;         
876       sw_printf("[%s:%u] - Failed to exec %s: %s\n", __FILE__, __LINE__, 
877                 executable.c_str(), strerror(errnum));
878       if (errnum == ENOENT)
879          setLastError(err_nofile, "No such file");
880       if (errnum == EPERM || errnum == EACCES)
881          setLastError(err_prem, "Premission denied");
882       else
883          setLastError(err_internal, "Unable to exec process");
884       exit(-1);
885    }
886    return true;
887 }
888
889 SigHandlerStepperImpl::SigHandlerStepperImpl(Walker *w, DebugStepper *parent) :
890    FrameStepper(w),
891    parent_stepper(parent)
892 {
893 }
894
895 unsigned SigHandlerStepperImpl::getPriority() const
896 {
897    return 0x10005;
898 }
899
900 void SigHandlerStepperImpl::registerStepperGroupNoSymtab(StepperGroup *group)
901 {
902    /**
903     * We don't have symtabAPI loaded, and we want to figure out where 
904     * the SigHandler trampolines are.  If we're a first-party stackwalker
905     * we can just use the entire vsyscall page.  
906     *
907     * We're not in danger of confusing the location with a regular system call,
908     * as we're not running in a system call right now.  I can't
909     * make that guarentee for a third-party stackwalker.  
910     **/   
911    ProcessState *ps = getProcessState();
912    assert(ps);
913
914    if (!dynamic_cast<ProcSelf *>(ps)) {
915       //Not a first-party stackwalker
916       return;
917    }
918       
919    AuxvParser *parser = AuxvParser::createAuxvParser(ps->getProcessId(),
920                                                      ps->getAddressWidth());
921    if (!parser) {
922       sw_printf("[%s:%u] - Unable to parse auxv for %d\n", __FILE__, __LINE__,
923                 ps->getProcessId());
924       return;
925    }
926
927    Address start = parser->getVsyscallBase();
928    Address end = parser->getVsyscallEnd();
929    sw_printf("[%s:%u] - Registering signal handler stepper over range %lx to %lx\n",
930              __FILE__, __LINE__, start, end);
931    
932    parser->deleteAuxvParser();
933    
934    if (!start || !end)
935    {
936       sw_printf("[%s:%u] - Error collecting vsyscall base and end\n",
937                 __FILE__, __LINE__);
938       return;
939    }
940
941    group->addStepper(parent_stepper, start, end);
942 }
943
944 SigHandlerStepperImpl::~SigHandlerStepperImpl()
945 {
946 }
947
948 #define MAX_TRAP_LEN 8
949 void ProcDebugLinux::registerLibSpotter()
950 {
951    if (lib_load_trap)
952       return;
953
954    LibraryState *libs = getLibraryTracker();
955    if (!libs) {
956       sw_printf("[%s:%u] - Not using lib tracker, don't know how "
957                 "to get library load address\n", __FILE__, __LINE__);
958       return;
959    }
960    
961    lib_load_trap = libs->getLibTrapAddress();
962    if (!lib_load_trap) {
963       sw_printf("[%s:%u] - Couldn't get trap addr, couldn't set up "
964                 "library loading notification.\n", __FILE__, __LINE__);
965       return;
966    }
967
968    char trap_buffer[MAX_TRAP_LEN];
969    unsigned actual_len;
970    getTrapInstruction(trap_buffer, MAX_TRAP_LEN, actual_len, true);
971
972    bool result = PtraceBulkWrite(lib_load_trap, actual_len, trap_buffer, pid);
973    if (!result) {
974       sw_printf("[%s:%u] - Error writing trap to %lx, couldn't set up library "
975                 "load address\n", __FILE__, __LINE__, lib_load_trap);
976       return;
977    }
978    sw_printf("[%s:%u] - Successfully installed library trap at %lx\n",
979              __FILE__, __LINE__, lib_load_trap);
980 }
981
982 static LibraryState *local_lib_state = NULL;
983 extern "C" {
984    static void lib_trap_handler(int sig);
985 }
986 static void lib_trap_handler(int /*sig*/)
987 {
988    local_lib_state->notifyOfUpdate();
989 }
990
991 static Address lib_trap_addr_self = 0x0;
992 static bool lib_trap_addr_self_err = false;
993 static void registerLibSpotterSelf(ProcSelf *pself)
994 {
995    if (lib_trap_addr_self)
996       return;
997    if (lib_trap_addr_self_err)
998       return;
999
1000    //Get the address to install a trap to
1001    LibraryState *libs = pself->getLibraryTracker();
1002    if (!libs) {
1003       sw_printf("[%s:%u] - Not using lib tracker, don't know how "
1004                 "to get library load address\n", __FILE__, __LINE__);
1005       lib_trap_addr_self_err = true;
1006       return;
1007    }   
1008    lib_trap_addr_self = libs->getLibTrapAddress();
1009    if (!lib_trap_addr_self) {
1010       sw_printf("[%s:%u] - Error getting trap address, can't install lib tracker",
1011                 __FILE__, __LINE__);
1012       lib_trap_addr_self_err = true;
1013       return;
1014    }
1015
1016    //Use /proc/PID/maps to make sure that this address is valid and writable
1017    unsigned maps_size;
1018    map_entries *maps = getLinuxMaps(getpid(), maps_size);
1019    if (!maps) {
1020       sw_printf("[%s:%u] - Error reading proc/%d/maps.  Can't install lib tracker",
1021                 __FILE__, __LINE__, getpid());
1022       lib_trap_addr_self_err = true;
1023       return;
1024    }
1025
1026    bool found = false;
1027    for (unsigned i=0; i<maps_size; i++) {
1028       if (maps[i].start <= lib_trap_addr_self && 
1029           maps[i].end > lib_trap_addr_self)
1030       {
1031          found = true;
1032          if (maps[i].prems & PREMS_WRITE) {
1033             break;
1034          }
1035          int pgsize = getpagesize();
1036          Address first_page = (lib_trap_addr_self / pgsize) * pgsize;
1037          unsigned size = pgsize;
1038          if (first_page + size < lib_trap_addr_self+MAX_TRAP_LEN)
1039             size += pgsize;
1040          int result = mprotect((void*) first_page,
1041                                size, 
1042                                PROT_READ|PROT_WRITE|PROT_EXEC);
1043          if (result == -1) {
1044             int errnum = errno;
1045             sw_printf("[%s:%u] - Error setting premissions for page containing %lx. "
1046                       "Can't install lib tracker: %s\n", __FILE__, __LINE__, 
1047                       lib_trap_addr_self, strerror(errnum));
1048             free(maps);
1049             lib_trap_addr_self_err = true;
1050             return;
1051          }
1052       }
1053    }
1054    free(maps);
1055    if (!found) {
1056       sw_printf("[%s:%u] - Couldn't find page containing %lx.  Can't install lib "
1057                 "tracker.", __FILE__, __LINE__, lib_trap_addr_self);
1058       lib_trap_addr_self_err = true;
1059       return;
1060    }
1061
1062    char trap_buffer[MAX_TRAP_LEN];
1063    unsigned actual_len;
1064    getTrapInstruction(trap_buffer, MAX_TRAP_LEN, actual_len, true);
1065
1066    local_lib_state = libs;
1067    signal(SIGTRAP, lib_trap_handler);
1068
1069    memcpy((void*) lib_trap_addr_self, trap_buffer, actual_len);   
1070    sw_printf("[%s:%u] - Successfully install lib tracker at 0x%lx\n",
1071             __FILE__, __LINE__, lib_trap_addr_self);
1072 }
1073
1074 #if defined(cap_stackwalker_use_symtab)
1075
1076 #include "common/h/parseauxv.h"
1077 #include "symtabAPI/h/Symtab.h"
1078 #include "symtabAPI/h/Symbol.h"
1079
1080 using namespace Dyninst::SymtabAPI;
1081
1082 bool SymtabLibState::updateLibsArch()
1083 {
1084    if (vsyscall_page_set == vsys_set)
1085    {
1086       return true;
1087    }
1088    else if (vsyscall_page_set == vsys_error)
1089    {
1090       return false;
1091    }
1092    else if (vsyscall_page_set == vsys_none)
1093    {
1094       return true;
1095    }
1096    assert(vsyscall_page_set == vsys_unset);
1097
1098 #if !defined(arch_x86)
1099    vsyscall_page_set = vsys_none;
1100    return true;
1101 #endif
1102       
1103    AuxvParser *parser = AuxvParser::createAuxvParser(procstate->getProcessId(), 
1104                                                      procstate->getAddressWidth());
1105    if (!parser) {
1106       sw_printf("[%s:%u] - Unable to parse auxv", __FILE__, __LINE__);
1107       vsyscall_page_set = vsys_error;
1108       return false;
1109    }
1110
1111    Address start = parser->getVsyscallBase();
1112    Address end = parser->getVsyscallEnd();
1113
1114    vsyscall_mem = malloc(end - start);
1115    bool result = procstate->readMem(vsyscall_mem, start, end - start);
1116    if (!result) {
1117       sw_printf("[%s:%u] - Error reading from vsyscall page\n");
1118       vsyscall_page_set = vsys_error;
1119       return false;
1120    }
1121
1122    std::stringstream ss;
1123    ss << "[vsyscall-" << procstate->getProcessId() << "]";
1124    LibAddrPair vsyscall_page;
1125    vsyscall_page.first = ss.str();
1126    vsyscall_page.second = start;
1127    
1128    result = Symtab::openFile(vsyscall_symtab, (char *) vsyscall_mem, end - start);
1129    if (!result || !vsyscall_symtab) {
1130       //TODO
1131       vsyscall_page_set = vsys_error;
1132       return false;
1133    }
1134
1135    SymtabWrapper::notifyOfSymtab(vsyscall_symtab, vsyscall_page.first);
1136    parser->deleteAuxvParser();
1137
1138    std::pair<LibAddrPair, unsigned int> vsyscall_lib_pair;
1139    vsyscall_lib_pair.first = vsyscall_page;
1140    vsyscall_lib_pair.second = static_cast<unsigned int>(end - start);
1141
1142    arch_libs.push_back(vsyscall_lib_pair);
1143    vsyscall_page_set = vsys_set;
1144
1145    return true;
1146 }
1147
1148 Symtab *SymtabLibState::getVsyscallSymtab()
1149 {
1150    refresh();
1151    if (vsyscall_page_set == vsys_set)
1152       return vsyscall_symtab;
1153    return NULL;
1154 }
1155
1156 #define NUM_VSYS_SIGRETURNS 3
1157 static const char* vsys_sigreturns[] = {
1158    "_sigreturn",
1159    "__kernel_sigreturn",
1160    "__kernel_rt_sigreturn"
1161 };
1162
1163 void SigHandlerStepperImpl::registerStepperGroup(StepperGroup *group)
1164 {
1165    LibraryState *libs = getProcessState()->getLibraryTracker();
1166    SymtabLibState *symtab_libs = dynamic_cast<SymtabLibState *>(libs);
1167    bool result;
1168    if (!symtab_libs) {
1169       sw_printf("[%s:%u] - Custom library tracker.  Don't know how to"
1170                 " to get vsyscall page\n", __FILE__, __LINE__);
1171       registerStepperGroupNoSymtab(group);
1172       return;
1173    }
1174    Symtab *vsyscall = symtab_libs->getVsyscallSymtab();
1175    if (!vsyscall)
1176    {
1177       sw_printf("[%s:%u] - Odd.  Couldn't find vsyscall page. Signal handler"
1178                 " stepping may not work\n", __FILE__, __LINE__);
1179       registerStepperGroupNoSymtab(group);
1180       return;
1181    }
1182
1183    for (unsigned i=0; i<NUM_VSYS_SIGRETURNS; i++)
1184    {
1185       std::vector<SymtabAPI::Symbol *> syms;
1186       result = vsyscall->findSymbolByType(syms, vsys_sigreturns[i], 
1187                                           SymtabAPI::Symbol::ST_FUNCTION);
1188       if (!result || !syms.size()) {
1189          continue;
1190       }
1191       Address addr = syms[0]->getAddr();
1192       unsigned long size = syms[0]->getSize();
1193       sw_printf("[%s:%u] - Registering signal handler stepper %s to run between"
1194                 " %lx and %lx\n", __FILE__, __LINE__, vsys_sigreturns[i], 
1195                 addr, addr+size);
1196       if (!size)
1197          size = getProcessState()->getAddressWidth();
1198       group->addStepper(parent_stepper, addr, addr + size);
1199    }
1200 }
1201
1202 #else
1203 void SigHandlerStepperImpl::registerStepperGroup(StepperGroup *group)
1204 {
1205    registerStepperGroupNoSymtab(group);
1206 }
1207 #endif
1208
1209 ThreadState* ThreadState::createThreadState(ProcDebug *parent,
1210                                             Dyninst::THR_ID id,
1211                                             bool already_attached)
1212 {
1213    assert(parent);
1214    Dyninst::THR_ID tid = id;
1215    if (id == NULL_THR_ID) {
1216       tid = (Dyninst::THR_ID) parent->getProcessId();
1217    }
1218    else {
1219       tid = id;
1220    }
1221    
1222    ThreadState *newts = new ThreadState(parent, tid);
1223    sw_printf("[%s:%u] - Creating new ThreadState %p for %d/%d\n",
1224              __FILE__, __LINE__, newts, parent->getProcessId(), tid);
1225    if (!newts || newts->state() == ps_errorstate) {
1226       sw_printf("[%s:%u] - Error creating new thread\n",
1227                 __FILE__, __LINE__);
1228       return NULL;
1229    }
1230    if (already_attached) {
1231       newts->setState(ps_attached_intermediate);
1232    }
1233
1234    ProcDebug::thread_map_t::iterator i = ProcDebugLinux::all_threads.find(tid);
1235    assert(i == ProcDebugLinux::all_threads.end() || 
1236           (*i).second->state() == ps_exited);
1237    ProcDebugLinux::all_threads[tid] = newts;
1238    parent->threads[tid] = newts;
1239
1240    if (id == NULL_THR_ID) {
1241       //Done with work for initial thread
1242       return newts;
1243    }
1244
1245    bool result;
1246
1247    if (newts->state() == ps_neonatal) {
1248       result = parent->debug_attach(newts);
1249       if (!result && getLastError() == err_procexit) {
1250          sw_printf("[%s:%u] - Thread %d exited before attach\n", 
1251                    __FILE__, __LINE__, tid);
1252          newts->setState(ps_exited);
1253          return NULL;
1254       }
1255       else if (!result) {
1256          sw_printf("[%s:%u] - Unknown error attaching to thread %d\n",
1257                    __FILE__, __LINE__, tid);
1258          newts->setState(ps_errorstate);
1259          return NULL;
1260       }
1261    }
1262    result = parent->debug_waitfor_attach(newts);
1263    if (!result) {
1264       sw_printf("[%s:%u] - Error waiting for attach on %d\n", 
1265                 __FILE__, __LINE__, tid);
1266       return NULL;
1267    }
1268
1269    result = parent->debug_post_attach(newts);
1270    if (!result) {
1271       sw_printf("[%s:%u] - Error in post attach on %d\n",
1272                 __FILE__, __LINE__, tid);
1273       return NULL;
1274    }
1275
1276    result = parent->resume_thread(newts);
1277    if (!result) {
1278       sw_printf("[%s:%u] - Error resuming thread %d\n",
1279                 __FILE__, __LINE__, tid);
1280    }
1281    
1282    return newts;
1283 }
1284
1285 SigHandlerStepper::SigHandlerStepper(Walker *w) :
1286    FrameStepper(w)
1287 {
1288    impl = new SigHandlerStepperImpl(w, (DebugStepper *) this);
1289 }
1290
1291 gcframe_ret_t SigHandlerStepper::getCallerFrame(const Frame &in, Frame &out)
1292 {
1293    if (impl)
1294       return impl->getCallerFrame(in, out);
1295    sw_printf("[%s:%u] - Error, signal handler walker used on unsupported platform\n",
1296              __FILE__, __LINE__);
1297    setLastError(err_unsupported, "Signal handling walking not supported on this platform");
1298    return gcf_error;
1299 }
1300
1301 unsigned SigHandlerStepper::getPriority() const
1302 {
1303    if (impl)
1304       return impl->getPriority();
1305    sw_printf("[%s:%u] - Error, signal handler walker used on unsupported platform\n",
1306              __FILE__, __LINE__);
1307    setLastError(err_unsupported, "Signal handling walking not supported on this platform");
1308    return 0;
1309 }
1310
1311 void SigHandlerStepper::registerStepperGroup(StepperGroup *group)
1312 {
1313    if (impl) {
1314       impl->registerStepperGroup(group);
1315       return;
1316    }
1317    sw_printf("[%s:%u] - Error, signal handler walker used on unsupported "
1318              "platform\n",  __FILE__, __LINE__);
1319    setLastError(err_unsupported, "Signal handling walking not supported on" 
1320                 " this platform");
1321 }
1322
1323 SigHandlerStepper::~SigHandlerStepper()
1324 {
1325    if (impl)
1326       delete impl;
1327    impl = NULL;
1328 }