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