Move debuglink location processing from SymtabAPI to Elf_X, so that it's accessible...
[dyninst.git] / stackwalk / src / linux-swk.C
1 /*
2  * Copyright (c) 1996-2011 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 #include "stackwalk/h/procstate.h"
37 #include "stackwalk/h/frame.h"
38
39 #include "stackwalk/src/linux-swk.h"
40 #include "stackwalk/src/sw.h"
41 #include "stackwalk/src/symtab-swk.h"
42 #include "stackwalk/src/libstate.h"
43
44 #include "common/h/linuxKludges.h"
45 #include "common/h/parseauxv.h"
46 #include "common/h/Types.h"
47
48 #include <string>
49 #include <sstream>
50
51 #include <string.h>
52 #include <sys/syscall.h>
53 #include <unistd.h>
54 #include <errno.h>
55 #include <assert.h>
56 #include <signal.h>
57 #include <sys/types.h>
58 #include <sys/wait.h>
59 #include <sys/mman.h>
60 #include <fcntl.h>
61 #include <poll.h>
62
63 #include "common/h/SymLite-elf.h"
64 #include "common/h/parseauxv.h"
65 #include "dynutil/h/dyn_regs.h"
66
67 using namespace Dyninst;
68 using namespace Dyninst::Stackwalker;
69
70 #ifndef SYS_tkill
71 #define SYS_tkill 238
72 #endif
73
74 //These should be defined on all modern linux's, turn these off
75 // if porting to some linux-like platform that doesn't support 
76 // them.
77 #include <sys/ptrace.h>
78 #include <linux/ptrace.h>
79 typedef enum __ptrace_request pt_req;
80 #define cap_ptrace_traceclone
81 #define cap_ptrace_setoptions
82
83 ProcDebug::thread_map_t ProcDebugLinux::all_threads;
84 std::map<pid_t, int> ProcDebugLinux::unknown_pid_events;
85
86 static int P_gettid()
87 {
88   static int gettid_not_valid = 0;
89   long int result;
90
91   if (gettid_not_valid)
92     return getpid();
93
94   result = syscall(SYS_gettid);
95   if (result == -1 && errno == ENOSYS)
96   {
97     gettid_not_valid = 1;
98     return getpid();
99   }
100   return (int) result;
101 }
102
103 static bool t_kill(int pid, int sig)
104 {
105   static bool has_tkill = true;
106   long int result = 0;
107   sw_printf("[%s:%u] - Sending %d to %d\n", __FILE__, __LINE__, sig, pid);
108   if (has_tkill) {
109      result = syscall(SYS_tkill, pid, sig);
110      if (result == -1 && errno == ENOSYS)
111      {
112         sw_printf("[%s:%d] - Using kill instead of tkill on this system\n", 
113                   __FILE__, __LINE__, sig, pid);
114         has_tkill = false;
115      }
116   }
117   if (!has_tkill) {
118      result = kill(pid, sig);
119   }
120
121   return (result == 0);
122 }
123
124 SymbolReaderFactory *Dyninst::Stackwalker::getDefaultSymbolReader()
125 {
126    static SymElfFactory symelffact;
127    if (!Walker::symrfact)
128       Walker::symrfact = (SymbolReaderFactory *) &symelffact;
129    return Walker::symrfact;
130 }
131
132 class Elf_X;
133 Elf_X *getElfHandle(std::string s)
134 {
135    SymbolReaderFactory *fact = getDefaultSymbolReader();
136    SymReader *reader = fact->openSymbolReader(s);
137    if (!reader)
138       return NULL;
139    return reader->getElfHandle();
140 }
141
142 static void registerLibSpotterSelf(ProcSelf *pself);
143
144 ProcSelf::ProcSelf(std::string exe_path) :
145    ProcessState(getpid(), exe_path)
146 {
147 }
148
149 void ProcSelf::initialize()
150 {
151    setDefaultLibraryTracker();
152    assert(library_tracker);
153    registerLibSpotterSelf(this);
154 }
155
156 #if defined(cap_sw_catchfaults)
157
158 #include <setjmp.h>
159
160 static bool registered_handler = false;
161 static bool reading_memory = false;
162 sigjmp_buf readmem_jmp;
163
164 void handle_fault(int /*sig*/)
165 {
166    if (!reading_memory) {
167       //The instruction that caused this fault was not from
168       // ProcSelf::readMem.  Restore the SIGSEGV handler, and 
169       // the faulting instruction should restart after we return.
170       fprintf(stderr, "[%s:%u] - Caught segfault that didn't come " \
171               "from stackwalker memory read!", __FILE__, __LINE__);
172       signal(SIGSEGV, SIG_DFL);
173       return;
174    }
175    siglongjmp(readmem_jmp, 1);
176 }
177
178 bool ProcSelf::readMem(void *dest, Address source, size_t size)
179 {
180    if (!registered_handler) {
181       signal(SIGSEGV, handle_fault);
182       registered_handler = true;
183    }
184    reading_memory = true;
185    if (sigsetjmp(readmem_jmp, 1)) {
186       sw_printf("[%s:%u] - Caught fault while reading from %lx to %lx\n", 
187                 __FILE__, __LINE__, source, source + size);
188       setLastError(err_procread, "Could not read from process");
189       return false;
190    }
191    
192    memcpy(dest, (const void *) source, size);
193    reading_memory = false;
194    return true;
195 }
196 #else
197 bool ProcSelf::readMem(void *dest, Address source, size_t size)
198 {
199   memcpy(dest, (const void *) source, size);
200   return true;
201 }
202 #endif
203
204 bool ProcSelf::getThreadIds(std::vector<THR_ID> &threads)
205 {
206   bool result;
207   THR_ID tid;
208
209   result = getDefaultThread(tid);
210   if (!result) {
211     sw_printf("[%s:%u] - Could not read default thread\n",
212                __FILE__, __LINE__);
213     return false;
214   }
215   threads.clear();
216   threads.push_back(tid);
217   return true;
218 }
219
220 bool ProcDebugLinux::isLibraryTrap(Dyninst::THR_ID thrd)
221 {
222    LibraryState *ls = getLibraryTracker();
223    if (!ls)
224       return false;
225    Address lib_trap_addr = ls->getLibTrapAddress();
226    if (!lib_trap_addr)
227       return false;
228
229    MachRegisterVal cur_pc;
230    MachRegister reg = MachRegister::getPC(getArchitecture());
231    bool result = getRegValue(reg, thrd, cur_pc);
232    if (!result) {
233       sw_printf("[%s:%u] - Error getting PC value for thrd %d\n",
234                 __FILE__, __LINE__, (int) thrd);
235       return false;
236    }
237    if (cur_pc == lib_trap_addr || cur_pc-1 == lib_trap_addr)
238       return true;
239    return false;
240 }
241
242
243 bool ProcSelf::getDefaultThread(THR_ID &default_tid)
244 {
245   THR_ID tid = P_gettid();
246   if (tid == -1) {
247     const char *sys_err_msg = strerror(errno);
248     sw_printf("[%s:%u] - gettid syscall failed with %s\n",
249                __FILE__, __LINE__, sys_err_msg);
250     std::string errmsg("gettid syscall failed with ");
251     errmsg += sys_err_msg;
252     setLastError(err_internal, errmsg.c_str());
253     return false;
254   }
255
256   default_tid = tid;
257   return true;
258 }
259
260 static bool pipeHasData(int fd)
261 {
262    if (fd == -1)
263       return false;
264
265    struct pollfd pfd[1];
266    pfd[0].fd = fd;
267    pfd[0].events = POLLIN;
268    pfd[0].revents = 0;
269    int result = poll(pfd, 1, 0);
270    return (result == 1 && pfd[0].revents & POLLIN);
271 }
272
273 DebugEvent ProcDebug::debug_get_event(bool block)
274 {
275    int status = 0;
276    DebugEvent ev;
277    pid_t p;
278
279    bool dataOnPipe = pipeHasData(pipe_out);
280
281    int flags = __WALL;
282    if (!block)
283      flags |= WNOHANG;
284    sw_printf("[%s:%u] - Calling waitpid(-1, %p, %s)\n",
285              __FILE__, __LINE__, &status, block ? "WALL|WNOHANG" : "WALL");
286    p = waitpid(-1, &status, flags);
287    sw_printf("[%s:%u] - waitpid returned status = 0x%x, p = %d\n",
288              __FILE__, __LINE__, status, p);
289    if (p == -1) {
290       int errnum = errno;
291       sw_printf("[%s:%u] - Unable to wait for debug event: %s\n",
292                 __FILE__, __LINE__, strerror(errnum));
293       if (errnum == EINTR)
294          setLastError(err_interrupt, "System call interrupted");
295       else
296          setLastError(err_internal, "Error calling waitpid");
297       ev.dbg = dbg_err;
298       return ev;
299    }
300
301    //If we got an event, or if we didn't read a message and there
302    // is a byte on the pipe, then remove one byte from the pipe.
303    if (pipe_out != -1 && 
304        (p != 0 || dataOnPipe)) 
305    {
306       char c;
307       sw_printf("[%s:%u] - Removing data from pipe, %d, %s\n",
308                 __FILE__, __LINE__, p, dataOnPipe ? "true" : "false");
309       read(pipe_out, &c, 1);
310    }
311    
312    if (p == 0) {
313      sw_printf("[%s:%u] - No debug events available\n", __FILE__, __LINE__);
314      ev.dbg = dbg_noevent;
315      return ev;
316    }
317
318    thread_map_t::iterator i = ProcDebugLinux::all_threads.find(p);
319    if (i == ProcDebugLinux::all_threads.end())
320    {
321       sw_printf("[%s:%u] - Warning, recieved unknown pid %d from waitpid\n",
322                 __FILE__, __LINE__, p);
323       ProcDebugLinux::unknown_pid_events[p] = status;
324       ev.dbg = dbg_noevent;
325       return ev;
326    }
327    
328    ev.thr = i->second;
329    ev.proc = ev.thr->proc();
330
331    if (WIFEXITED(status)) 
332    {
333       ev.dbg = dbg_exited;
334       ev.data.idata = WEXITSTATUS(status);
335       sw_printf("[%s:%u] - Process %d exited with %d\n", 
336                 __FILE__, __LINE__, p, ev.dbg);
337    }
338    else if (WIFSIGNALED(status))
339    {
340       ev.dbg = dbg_crashed;
341       ev.data.idata = WTERMSIG(status);
342       sw_printf("[%s:%u] - Process %d crashed with %d\n", 
343                 __FILE__, __LINE__, p, ev.dbg);
344    }
345    else if (WIFSTOPPED(status))
346    {
347       ev.dbg = dbg_stopped;
348       ev.data.idata = WSTOPSIG(status);
349       
350       ProcDebugLinux *linux_proc = dynamic_cast<ProcDebugLinux*>(ev.proc);
351       assert(linux_proc);
352       if (ev.data.idata == SIGTRAP) {
353          if (linux_proc->state() == ps_running && 
354              linux_proc->isLibraryTrap((Dyninst::THR_ID) p)) 
355          {
356             sw_printf("[%s:%u] - Decoded library load event\n",
357                       __FILE__, __LINE__);
358             ev.dbg = dbg_libraryload;
359          }
360          else {
361             int extended_data = status >> 16;
362             if (extended_data)
363                ev.data.idata = (extended_data << 8) | SIGTRAP;
364          }
365       }
366       sw_printf("[%s:%u] - Process %d stopped with %d\n",
367                 __FILE__, __LINE__, p, ev.data);
368    }
369    else
370    {
371       sw_printf("[%s:%u] - Process %d had strange return value from waitpid\n",
372                 __FILE__, __LINE__, p);
373       setLastError(err_internal, "Error calling waitpid");
374       ev.dbg = dbg_err;
375    }
376    return ev;
377 }
378
379 bool ProcDebugLinux::debug_handle_event(DebugEvent ev)
380 {
381   bool result;
382   ThreadState *thr = ev.thr;
383
384   switch (ev.dbg)
385   {
386      case dbg_stopped:
387         thr->setStopped(true);
388         if (thr->state() == ps_attached_intermediate && 
389             (ev.data.idata == SIGSTOP || ev.data.idata == SIGTRAP)) {
390            sw_printf("[%s:%u] - Moving %d/%d to state running\n", 
391                      __FILE__, __LINE__, pid, thr->getTid());
392            thr->setState(ps_running);
393            return true;
394         }
395
396 #if defined(cap_ptrace_traceclone)
397         if (ev.data.idata == (SIGTRAP | (PTRACE_EVENT_CLONE << 8))) {
398            sw_printf("[%s:%u] - Discovered new thread in proc %d\n", 
399                      __FILE__, __LINE__, pid);
400            ThreadState *new_thread = NULL;
401            unsigned long newtid_l = 0x0;
402            long iresult = ptrace((pt_req) PTRACE_GETEVENTMSG, thr->getTid(), 
403                                  NULL, &newtid_l);
404            pid_t newtid = (pid_t) newtid_l;
405            if (iresult == -1) {
406               sw_printf("[%s:%u] - Unexpected error getting new tid on %d\n"
407                      __FILE__, __LINE__, pid);
408            }
409            else 
410            {
411               sw_printf("[%s:%u] - New thread %ld in proc %d\n",
412                         __FILE__, __LINE__, newtid, pid);
413               new_thread = ThreadState::createThreadState(this, (THR_ID) newtid, true);
414            }
415            if (!new_thread) {
416               sw_printf("[%s:%u] - Error creating thread %d in proc %d\n",
417                         __FILE__, __LINE__, newtid, pid);
418            }
419            result = debug_continue(thr);
420            if (!result) {
421               sw_printf("[%s:%u] - Debug continue failed on %d/%d\n",
422                         __FILE__, __LINE__, pid, thr->getTid());
423               return false;
424            }
425            return true;
426         }
427 #endif
428         
429         result = debug_handle_signal(&ev);
430         if (!result) {
431           sw_printf("[%s:%u] - Debug continue failed on %d/%d with %d\n", 
432                     __FILE__, __LINE__, pid, thr->getTid(), ev.data.idata);
433           return false;
434         }
435
436         return true;
437     case dbg_libraryload: 
438     {
439        sw_printf("[%s:%u] - Handling library load event on %d/%d\n",
440                  __FILE__, __LINE__, pid, thr->getTid());
441        thr->setStopped(true);
442        LibraryState *ls = getLibraryTracker();
443        assert(ls);
444        ls->notifyOfUpdate();
445
446 #if defined(arch_power)
447        /**
448         * Forward over the trap instruction
449         **/
450        Dyninst::MachRegisterVal newpc = ls->getLibTrapAddress() + 4;
451        bool result = setRegValue(Dyninst::ReturnAddr, thr->getTid(), newpc);
452        if (!result) {
453          sw_printf("[%s:%u] - Error! Could not set PC past trap!\n",
454                    __FILE__, __LINE__);
455          setLastError(err_internal, "Could not set PC after trap\n");
456          return false;
457        }
458 #endif
459        result = debug_continue_with(thr, 0);
460        if (!result) {
461           sw_printf("[%s:%u] - Debug continue failed on %d/%d with %d\n", 
462                     __FILE__, __LINE__, pid, thr->getTid(), ev.data.idata);
463           return false;
464        }
465        return true;
466     }
467     case dbg_crashed:
468       sw_printf("[%s:%u] - Handling process crash on %d/%d\n",
469                 __FILE__, __LINE__, pid, thr->getTid());
470     case dbg_exited:
471       sw_printf("[%s:%u] - Handling process death on %d/%d\n",
472                 __FILE__, __LINE__, pid, thr->getTid());
473       thr->setState(ps_exited);
474       return true;
475     case dbg_err:
476     case dbg_noevent:
477     default:
478       sw_printf("[%s:%u] - Unexpectedly handling an error event %d on %d/%d\n", 
479                 __FILE__, __LINE__, ev.dbg, pid, thr->getTid());
480       setLastError(err_internal, "Told to handle an unexpected event.");
481       return false;
482   }
483 }
484
485 bool ProcDebugLinux::debug_handle_signal(DebugEvent *ev)
486 {
487    assert(ev->dbg == dbg_stopped);
488    int sig = ev->data.idata;
489    ThreadState *thr = ev->thr;
490    if (sigfunc) {
491       bool user_stopped = thr->userIsStopped();
492       thr->setUserStopped(true);
493       sigfunc(sig, thr);
494       thr->setUserStopped(user_stopped);
495    }
496
497    if (sig == SIGSTOP)
498    {
499      if (thr->hasPendingStop()) {
500        //Leave process as is, no need to handle.
501        sw_printf("Clearing pending SIGSTOP\n");
502        thr->clearPendingStop();
503        return true;
504      }
505      sw_printf("Dropping SIGSTOP and continuing process\n");
506      //Continue past sigstop with-out a signal
507      sig = 0;
508    }
509
510    return debug_continue_with(thr, sig);
511 }
512
513 #if defined(cap_ptrace_setoptions)   
514 void ProcDebugLinux::setOptions(Dyninst::THR_ID tid)
515 {
516
517    long options = 0;
518 #if defined(cap_ptrace_traceclone)
519    options |= PTRACE_O_TRACECLONE;
520 #endif
521
522    if (options) {
523       int result = ptrace((pt_req) PTRACE_SETOPTIONS, tid, NULL, 
524                           (void *) options);
525       if (result == -1) {
526          sw_printf("[%s:%u] - Failed to set options for %d: %s\n", 
527                    __FILE__, __LINE__, tid, strerror(errno));
528       }
529    }   
530 }
531 #else
532 void ProcDebugLinux::setOptions(Dyninst::THR_ID)
533 {
534 }
535 #endif
536
537 bool ProcDebugLinux::debug_attach(ThreadState *ts)
538 {
539    long result;
540    pid_t tid = (pid_t) ts->getTid();
541    
542    sw_printf("[%s:%u] - Attaching to pid %d\n", __FILE__, __LINE__, tid);
543    result = ptrace((pt_req) PTRACE_ATTACH, tid, NULL, NULL);
544    if (result != 0) {
545       int errnum = errno;
546       sw_printf("[%s:%u] - Unable to attach to process %d: %s\n",
547                 __FILE__, __LINE__, tid, strerror(errnum));
548       if (errnum == EPERM)
549          setLastError(err_prem, "Do not have correct premissions to attach " \
550                       "to pid");
551       else if (errnum == ESRCH)
552          setLastError(err_noproc, "The specified process was not found");
553       else {
554          setLastError(err_internal, "DynStackwalker was unable to attach to " \
555                       "the specified process");
556       }
557       return false;
558    }
559    ts->setState(ps_attached_intermediate);   
560
561    return true;
562 }
563
564 bool ProcDebugLinux::debug_post_create()
565 {
566    sw_printf("[%s:%u] - Post create on %d\n", __FILE__, __LINE__, pid);
567    setOptions(pid);
568
569    setDefaultLibraryTracker();
570    assert(library_tracker);
571    registerLibSpotter();
572    return true;
573 }
574
575 bool ProcDebugLinux::debug_post_attach(ThreadState *thr)
576 {
577    sw_printf("[%s:%u] - Post attach on %d\n", __FILE__, __LINE__, thr->getTid());
578    THR_ID tid = thr->getTid();
579    setOptions(tid);
580
581    setDefaultLibraryTracker();
582    assert(library_tracker);
583    registerLibSpotter();
584
585    if (tid == pid) {
586       //We're attach to the initial process, also attach to all threads
587       pollForNewThreads();
588    }
589    return true;
590 }
591
592 bool ProcDebugLinux::debug_pause(ThreadState *thr)
593 {
594    bool result;
595
596    result = t_kill(thr->getTid(), SIGSTOP);
597    if (!result) {
598       if (errno == ESRCH) {
599          sw_printf("[%s:%u] - t_kill failed on %d, thread doesn't exist\n",
600                    __FILE__, __LINE__, thr->getTid());
601          setLastError(err_noproc, "Thread no longer exists");
602          return false;
603       }
604       sw_printf("[%s:%u] - t_kill failed on %d: %s\n", __FILE__, __LINE__,
605                 thr->getTid(), strerror(errno));
606       setLastError(err_internal, "Could not send signal to process while " \
607                    "stopping");
608       return false;
609    }
610    thr->markPendingStop();
611    
612    return true;
613 }
614
615 bool ProcDebugLinux::debug_continue(ThreadState *thr)
616 {
617    return debug_continue_with(thr, 0);
618 }
619
620 bool ProcDebugLinux::debug_continue_with(ThreadState *thr, long sig)
621 {
622    long result;
623    assert(thr->isStopped());
624    Dyninst::THR_ID tid = thr->getTid();
625    sw_printf("[%s:%u] - Calling PTRACE_CONT with signal %d on %d\n",
626              __FILE__, __LINE__, sig, tid);
627    result = ptrace((pt_req) PTRACE_CONT, tid, NULL, (void *) sig);
628    if (result != 0)
629    {
630      int errnum = errno;
631       sw_printf("[%s:%u] - Error continuing %d with %d: %s\n",
632                 __FILE__, __LINE__, tid, sig, strerror(errnum));
633       setLastError(err_internal, "Could not continue process");
634       return false;
635    }
636
637    thr->setStopped(false);
638    return true;
639 }
640
641 bool ProcDebugLinux::readMem(void *dest, Address source, size_t size)
642 {
643    unsigned long nbytes = size;
644    const unsigned char *ap = (const unsigned char*) source;
645    unsigned char *dp = (unsigned char*) dest;
646    Address w = 0x0;               /* ptrace I/O buffer */
647    int len = sizeof(long);
648    unsigned long cnt;
649    
650    if (!nbytes) {
651       return true;
652    }
653    
654    ThreadState *thr = active_thread;
655    if (!thr) {
656       //Likely doing this read in response to some event, perhaps
657       // without an active thread.  The event should have stopped something,
658       // so find a stopped thread.
659       thread_map_t::iterator i;
660       for (i = threads.begin(); i != threads.end(); i++) {
661          ThreadState *t = (*i).second;
662          if (t->state() == ps_exited)
663             continue;
664          if (t->isStopped()) {
665             thr = t;
666             break;
667          }
668       }
669    }
670    assert(thr); //Something should be stopped if we're here.
671    pid_t tid = (pid_t) thr->getTid();
672
673    if ((cnt = (source % len))) {
674       /* Start of request is not aligned. */
675       unsigned char *p = (unsigned char*) &w;
676       
677       /* Read the segment containing the unaligned portion, and
678          copy what was requested to DP. */
679       errno = 0;
680       w = ptrace((pt_req) PTRACE_PEEKTEXT, tid, (Address) (ap-cnt), w);
681       if (errno) {
682          int errnum = errno;
683          sw_printf("[%s:%u] - PTRACE_PEEKTEXT returned error on %d: %s\n",
684                    __FILE__, __LINE__, pid, strerror(errnum));
685          setLastError(err_procread, "Could not read from process\n");
686          return false;
687       }
688
689       for (unsigned i = 0; i < len-cnt && i < nbytes; i++)
690          dp[i] = p[cnt+i];
691       
692       if (len-cnt >= nbytes) {
693          return true;
694       }
695       
696       dp += len-cnt;
697       ap += len-cnt;
698       nbytes -= len-cnt;
699    }
700    /* Copy aligned portion */
701    while (nbytes >= (u_int)len) {
702       errno = 0;
703       w = ptrace((pt_req) PTRACE_PEEKTEXT, tid, (Address) ap, 0);
704       if (errno) {
705          int errnum = errno;
706          sw_printf("[%s:%u] - PTRACE_PEEKTEXT returned error on %d: %s\n",
707                    __FILE__, __LINE__, pid, strerror(errnum));
708          setLastError(err_procread, "Could not read from process\n");
709          return false;
710       }
711       memcpy(dp, &w, len);
712       dp += len;
713       ap += len;
714       nbytes -= len;
715    }
716    
717    if (nbytes > 0) {
718       /* Some unaligned data remains */
719       unsigned char *p = (unsigned char *) &w;
720       
721       /* Read the segment containing the unaligned portion, and
722          copy what was requested to DP. */
723       errno = 0;
724       w = ptrace((pt_req) PTRACE_PEEKTEXT, tid, (Address) ap, 0);
725       if (errno) {
726          int errnum = errno;
727          sw_printf("[%s:%u] - PTRACE_PEEKTEXT returned error on %d: %s\n",
728                    __FILE__, __LINE__, pid, strerror(errnum));
729          setLastError(err_procread, "Could not read from process\n");
730          return false;
731       }
732       for (unsigned i = 0; i < nbytes; i++)
733          dp[i] = p[i];
734    }
735
736    return true;
737 }   
738
739 bool ProcDebugLinux::getThreadIds(std::vector<THR_ID> &thrds)
740 {
741 #if !defined(cap_ptrace_traceclone)
742    pollForNewThreads();
743 #endif
744    thread_map_t::iterator i;
745    for (i = threads.begin(); i != threads.end(); i++) {
746       ThreadState *ts = (*i).second;
747       if (ts->state() != ps_running) {
748          sw_printf("Skipping thread %d in state %d\n", 
749                    ts->getTid(), ts->state());
750          continue;
751       }
752               
753       thrds.push_back(ts->getTid());
754    }
755    return true;
756 }
757
758 bool ProcDebugLinux::pollForNewThreads()
759 {
760    std::vector<THR_ID> thrds;
761    bool result = findProcLWPs(pid, thrds);
762    if (!result) {
763       sw_printf("[%s:%u] - getThreadIds failed in libcommon's findProcLWPs "
764                 "for %d", __FILE__, __LINE__, pid);                
765       return false;
766    }
767
768    return add_new_threads(thrds.begin(), thrds.end());
769 }
770
771 bool ProcDebugLinux::getDefaultThread(THR_ID &default_tid)
772 {
773    default_tid = (THR_ID) pid;
774    return true;
775 }
776
777 ProcDebugLinux::ProcDebugLinux(PID pid)
778    : ProcDebug(pid),
779      cached_addr_width(0),
780      lib_load_trap(0x0),
781      trap_actual_len(0x0),
782      trap_install_error(false)
783 {
784 }
785
786 ProcDebugLinux::ProcDebugLinux(std::string executable, 
787                                const std::vector<std::string> &argv)
788    : ProcDebug(executable, argv),
789      cached_addr_width(0),
790      lib_load_trap(0x0),
791      trap_actual_len(0x0),
792      trap_install_error(false)
793 {
794 }
795
796 ProcDebugLinux::~ProcDebugLinux()
797 {
798 }
799    
800 ProcDebug *ProcDebug::newProcDebug(PID pid, std::string)
801 {
802    ProcDebugLinux *pd = new ProcDebugLinux(pid);
803    if (!pd)
804    {
805       sw_printf("[%s:%u] - Error creating new ProcDebug object\n",
806                 __FILE__, __LINE__);
807       return pd;
808    }
809
810    bool result = pd->attach();
811    if (!result || pd->state() != ps_running) {
812      pd->setState(ps_errorstate);
813      proc_map.erase(pid);
814      sw_printf("[%s:%u] - Error attaching to process %d\n",
815                __FILE__, __LINE__, pid);
816      delete pd;
817      return NULL;
818    }
819
820    return pd;
821 }
822
823 ProcDebug *ProcDebug::newProcDebug(std::string executable, 
824                                    const std::vector<std::string> &argv)
825 {
826    ProcDebugLinux *pd = new ProcDebugLinux(executable, argv);
827    if (!pd)
828    {
829       sw_printf("[%s:%u] - Error creating new ProcDebug object\n",
830                 __FILE__, __LINE__);
831       return NULL;
832    }
833
834    bool result = pd->create(executable, argv);
835    if (!result || pd->state() != ps_running)
836    {
837      pd->setState(ps_errorstate);
838      proc_map.erase(pd->pid);
839      sw_printf("[%s:%u] - Error attaching to process %d\n",
840                __FILE__, __LINE__, pd->pid);
841      delete pd;
842      return NULL;
843    }
844
845    return pd;   
846 }
847
848 Dyninst::Architecture ProcDebug::getArchitecture()
849 {
850 #if defined(arch_power) && !defined(arch_64bit)
851    return Dyninst::Arch_ppc32;
852 #elif defined(arch_x86)
853    return Dyninst::Arch_x86;
854 #else
855    int addr_width = getAddressWidth();
856    if (addr_width == 4)
857    {
858 #if defined(arch_x86_64)
859       return Dyninst::Arch_x86;
860 #elif defined(arch_power)
861       return Dyninst::Arch_ppc32;
862 #endif
863    }
864    else if (addr_width == 8)
865    {
866 #if defined(arch_x86_64)
867       return Dyninst::Arch_x86_64;
868 #elif defined(arch_power)
869       return Dyninst::Arch_ppc64;
870 #endif
871    }
872 #endif
873    assert(0);
874    return Dyninst::Arch_none;
875 }
876
877
878 void chld_handler(int)
879 {
880    write(ProcDebug::pipe_in, "s", 1);
881 }
882
883 int ProcDebug::getNotificationFD()
884 {
885    static bool registered_handler = false;
886    int filedes[2], result;
887    if (!registered_handler) 
888    {
889       signal(SIGCHLD, chld_handler);
890       result = pipe(filedes);
891       if (result == -1)
892       {
893          int errnum = errno;
894          sw_printf("[%s:%u] - Could not create pipe: %s\n",
895                    __FILE__, __LINE__, strerror(errnum));
896          setLastError(err_internal, "Could not create pipe for notificationFD");
897          return -1;
898       }
899       pipe_out = filedes[0];
900       pipe_in = filedes[1];
901
902       result = fcntl(pipe_out, F_GETFL);
903       if (result != -1)
904       {
905          result = fcntl(pipe_out, F_SETFL, result | O_NONBLOCK);
906       }
907       if (result == -1)
908       {
909          int errnum = errno;
910          sw_printf("[%s:%u] - Could not set fcntl flags: %s\n",
911                    __FILE__, __LINE__, strerror(errnum));
912          setLastError(err_internal, "Could not set pipe properties");
913          return -1;
914       }
915       registered_handler = true;
916    }
917    return pipe_out;
918 }
919
920 bool ProcDebugLinux::debug_create(std::string executable, 
921                                   const std::vector<std::string> &argv)
922 {
923    pid = fork();
924    if (pid == -1)
925    {
926       int errnum = errno;
927       sw_printf("[%s:%u] - Could not fork new process for %s: %s\n",
928                 __FILE__, __LINE__, executable.c_str(), strerror(errnum));
929       setLastError(err_internal, "Unable to fork new process");
930       return false;
931    }
932
933    if (pid)
934    {
935    }
936    else
937    {
938       //Child
939       long int result = ptrace((pt_req) PTRACE_TRACEME, 0, 0, 0);
940       unsigned i;
941       if (result == -1)
942       {
943          sw_printf("[%s:%u] - Failed to execute a PTRACE_TRACME.  Odd.\n",
944                    __FILE__, __LINE__);
945          setLastError(err_internal, "Unable to debug trace new process");
946          exit(-1);
947       }
948
949       typedef const char * const_str;
950       
951       const_str *new_argv = (const_str *) calloc(argv.size()+3, sizeof(char *));
952       new_argv[0] = executable.c_str();
953       for (i=1; i<argv.size()+1; i++) {
954          new_argv[i] = argv[i-1].c_str();
955       }
956       new_argv[i+1] = (char *) NULL;
957       
958       result = execv(executable.c_str(), const_cast<char * const*>(new_argv));
959       int errnum = errno;         
960       sw_printf("[%s:%u] - Failed to exec %s: %s\n", __FILE__, __LINE__, 
961                 executable.c_str(), strerror(errnum));
962       if (errnum == ENOENT)
963          setLastError(err_nofile, "No such file");
964       if (errnum == EPERM || errnum == EACCES)
965          setLastError(err_prem, "Premission denied");
966       else
967          setLastError(err_internal, "Unable to exec process");
968       exit(-1);
969    }
970    return true;
971 }
972
973 vsys_info *Dyninst::Stackwalker::getVsysInfo(ProcessState *ps)
974 {
975 #if defined(arch_x86_64)
976    return NULL;
977 #endif
978
979    static std::map<ProcessState *, vsys_info *> vsysmap;
980    vsys_info *ret = NULL;
981    Address start, end;
982    char *buffer = NULL;
983    SymReader *reader = NULL;
984    SymbolReaderFactory *fact = NULL;
985    bool result;
986
987    std::map<ProcessState *, vsys_info *>::iterator i = vsysmap.find(ps);
988    if (i != vsysmap.end())
989       return i->second;
990    
991    AuxvParser *parser = AuxvParser::createAuxvParser(ps->getProcessId(),
992                                                      ps->getAddressWidth());
993    if (!parser) {
994       sw_printf("[%s:%u] - Unable to parse auxv for %d\n", __FILE__, __LINE__,
995                 ps->getProcessId());
996       goto done;
997    }
998
999    start = parser->getVsyscallBase();
1000    end = parser->getVsyscallEnd();
1001    sw_printf("[%s:%u] - Registering signal handler stepper over range %lx to %lx\n",
1002              __FILE__, __LINE__, start, end);   
1003    parser->deleteAuxvParser();
1004    
1005    if (!start || !end || end == start)
1006    {
1007       sw_printf("[%s:%u] - Error collecting vsyscall base and end\n",
1008                 __FILE__, __LINE__);
1009       goto done;
1010    }
1011
1012    ret = new vsys_info();
1013    assert(ret);
1014    ret->start = start;
1015    ret->end = end;
1016
1017    buffer = (char *) malloc(end - start);
1018    assert(buffer);
1019    result = ps->readMem(buffer, start, end - start);
1020    if (!result) {
1021       sw_printf("[%s:%u] - Error reading vsys memory\n", __FILE__, __LINE__);
1022       goto done;
1023    }
1024    ret->vsys_mem = buffer;
1025
1026    fact = getDefaultSymbolReader();
1027    if (!fact) {
1028       sw_printf("[%s:%u] - No symbol reading capability\n",
1029                 __FILE__, __LINE__);
1030       goto done;
1031    }   
1032    reader = fact->openSymbolReader(buffer, end - start);
1033    if (!reader) {
1034       sw_printf("[%s:%u] - Error reading symbol info\n");
1035       goto done;
1036    }
1037    ret->syms = reader;
1038
1039   done:
1040    vsysmap[ps] = ret;
1041    return ret;
1042 }
1043
1044 SigHandlerStepperImpl::SigHandlerStepperImpl(Walker *w, SigHandlerStepper *parent) :
1045    FrameStepper(w),
1046    parent_stepper(parent),
1047    init_libc(false),
1048    init_libthread(false)
1049 {
1050 }
1051
1052 unsigned SigHandlerStepperImpl::getPriority() const
1053 {
1054    return sighandler_priority;
1055 }
1056
1057 SigHandlerStepperImpl::~SigHandlerStepperImpl()
1058 {
1059 }
1060
1061 void SigHandlerStepperImpl::newLibraryNotification(LibAddrPair *, lib_change_t change)
1062 {
1063    if (change == library_unload)
1064       return;
1065    StepperGroup *group = getWalker()->getStepperGroup();
1066    registerStepperGroup(group);
1067 }
1068
1069 void ProcDebugLinux::registerLibSpotter()
1070 {
1071    bool result;
1072
1073    if (lib_load_trap)
1074       return;
1075
1076    LibraryState *libs = getLibraryTracker();
1077    if (!libs) {
1078       sw_printf("[%s:%u] - Not using lib tracker, don't know how "
1079                 "to get library load address\n", __FILE__, __LINE__);
1080       return;
1081    }
1082    
1083    lib_load_trap = libs->getLibTrapAddress();
1084    if (!lib_load_trap) {
1085       sw_printf("[%s:%u] - Couldn't get trap addr, couldn't set up "
1086                 "library loading notification.\n", __FILE__, __LINE__);
1087       trap_install_error = true;
1088       return;
1089    }
1090
1091    char trap_buffer[MAX_TRAP_LEN];
1092    getTrapInstruction(trap_buffer, MAX_TRAP_LEN, trap_actual_len, true);
1093
1094    result = PtraceBulkRead(lib_load_trap, trap_actual_len, trap_overwrite_buffer, pid);
1095    if (!result) {
1096       sw_printf("[%s:%u] - Error reading trap bytes from %lx\n", 
1097                 __FILE__, __LINE__, lib_load_trap);
1098       trap_install_error = true;
1099       return;
1100    }
1101    result = PtraceBulkWrite(lib_load_trap, trap_actual_len, trap_buffer, pid);
1102    if (!result) {
1103       sw_printf("[%s:%u] - Error writing trap to %lx, couldn't set up library "
1104                 "load address\n", __FILE__, __LINE__, lib_load_trap);
1105       trap_install_error = true;
1106       return;
1107    }
1108    sw_printf("[%s:%u] - Successfully installed library trap at %lx\n",
1109              __FILE__, __LINE__, lib_load_trap);
1110 }
1111
1112 bool ProcDebugLinux::detach_thread(int tid, bool leave_stopped)
1113 {
1114    sw_printf("[%s:%u] - Detaching from tid %d\n", __FILE__, __LINE__, tid);
1115    long int iresult = ptrace((pt_req) PTRACE_DETACH, tid, NULL, NULL);
1116    if (iresult == -1) {
1117       int error = errno;
1118       sw_printf("[%s:%u] - Error.  Couldn't detach from %d: %s\n",
1119                 __FILE__, __LINE__, tid, strerror(error));
1120       if (error != ESRCH) {
1121          setLastError(err_internal, "Could not detach from thread\n");
1122          return false;
1123       }
1124    }
1125
1126    thread_map_t::iterator j = all_threads.find(tid);
1127    if (j == all_threads.end()) {
1128       sw_printf("[%s:%u] - Error.  Expected to find %d in all threads\n",
1129                 __FILE__, __LINE__, tid);
1130       setLastError(err_internal, "Couldn't find thread in internal data structures");
1131       return false;
1132    }
1133
1134    if (!leave_stopped) {
1135       t_kill(tid, SIGCONT);
1136    }
1137
1138    all_threads.erase(j);
1139    return true;
1140 }
1141
1142 bool ProcDebugLinux::detach(bool leave_stopped)
1143 {
1144    bool result;
1145    bool error = false;
1146    sw_printf("[%s:%u] - Detaching from process %d\n", 
1147              __FILE__, __LINE__, getProcessId());
1148    result = pause();
1149    if (!result) {
1150       sw_printf("[%s:%u] - Error pausing process before detach\n",
1151                 __FILE__, __LINE__);
1152       return false;
1153    }
1154
1155    if (lib_load_trap && !trap_install_error)
1156    {
1157       result = PtraceBulkWrite(lib_load_trap, trap_actual_len, 
1158                                trap_overwrite_buffer, pid);
1159       if (!result) {
1160          sw_printf("[%s:%u] - Error.  Couldn't restore load trap bytes at %lx\n",
1161                    __FILE__, __LINE__, lib_load_trap);
1162          setLastError(err_internal, "Could not remove library trap");
1163          return false;
1164       }
1165       lib_load_trap = 0x0;
1166    }
1167
1168    if (leave_stopped) {
1169       kill(getProcessId(), SIGSTOP);
1170    }
1171    result = detach_thread(getProcessId(), leave_stopped);
1172    if (!result)
1173       error = true;
1174    
1175    for (thread_map_t::iterator i = threads.begin(); i != threads.end(); i++)
1176    {
1177       Dyninst::THR_ID tid = (*i).first;
1178       ThreadState *thread_state = (*i).second;
1179       if (tid == getProcessId())
1180          continue;
1181       result = detach_thread(tid, leave_stopped);
1182       if (!result)
1183          error = true;
1184
1185       delete thread_state;
1186    }
1187    threads.clear();
1188
1189    detach_arch_cleanup();
1190
1191    return !error;
1192 }
1193
1194
1195 static LibraryState *local_lib_state = NULL;
1196 extern "C" {
1197    static void lib_trap_handler(int sig);
1198 }
1199 static void lib_trap_handler(int /*sig*/)
1200 {
1201    local_lib_state->notifyOfUpdate();
1202 }
1203
1204 static Address lib_trap_addr_self = 0x0;
1205 static bool lib_trap_addr_self_err = false;
1206 static void registerLibSpotterSelf(ProcSelf *pself)
1207 {
1208    if (lib_trap_addr_self)
1209       return;
1210    if (lib_trap_addr_self_err)
1211       return;
1212
1213    //Get the address to install a trap to
1214    LibraryState *libs = pself->getLibraryTracker();
1215    if (!libs) {
1216       sw_printf("[%s:%u] - Not using lib tracker, don't know how "
1217                 "to get library load address\n", __FILE__, __LINE__);
1218       lib_trap_addr_self_err = true;
1219       return;
1220    }   
1221    lib_trap_addr_self = libs->getLibTrapAddress();
1222    if (!lib_trap_addr_self) {
1223       sw_printf("[%s:%u] - Error getting trap address, can't install lib tracker",
1224                 __FILE__, __LINE__);
1225       lib_trap_addr_self_err = true;
1226       return;
1227    }
1228
1229    //Use /proc/PID/maps to make sure that this address is valid and writable
1230    unsigned maps_size;
1231    map_entries *maps = getLinuxMaps(getpid(), maps_size);
1232    if (!maps) {
1233       sw_printf("[%s:%u] - Error reading proc/%d/maps.  Can't install lib tracker",
1234                 __FILE__, __LINE__, getpid());
1235       lib_trap_addr_self_err = true;
1236       return;
1237    }
1238
1239    bool found = false;
1240    for (unsigned i=0; i<maps_size; i++) {
1241       if (maps[i].start <= lib_trap_addr_self && 
1242           maps[i].end > lib_trap_addr_self)
1243       {
1244          found = true;
1245          if (maps[i].prems & PREMS_WRITE) {
1246             break;
1247          }
1248          int pgsize = getpagesize();
1249          Address first_page = (lib_trap_addr_self / pgsize) * pgsize;
1250          unsigned size = pgsize;
1251          if (first_page + size < lib_trap_addr_self+MAX_TRAP_LEN)
1252             size += pgsize;
1253          int result = mprotect((void*) first_page,
1254                                size, 
1255                                PROT_READ|PROT_WRITE|PROT_EXEC);
1256          if (result == -1) {
1257             int errnum = errno;
1258             sw_printf("[%s:%u] - Error setting premissions for page containing %lx. "
1259                       "Can't install lib tracker: %s\n", __FILE__, __LINE__, 
1260                       lib_trap_addr_self, strerror(errnum));
1261             free(maps);
1262             lib_trap_addr_self_err = true;
1263             return;
1264          }
1265       }
1266    }
1267    free(maps);
1268    if (!found) {
1269       sw_printf("[%s:%u] - Couldn't find page containing %lx.  Can't install lib "
1270                 "tracker.", __FILE__, __LINE__, lib_trap_addr_self);
1271       lib_trap_addr_self_err = true;
1272       return;
1273    }
1274
1275    char trap_buffer[MAX_TRAP_LEN];
1276    unsigned actual_len;
1277    getTrapInstruction(trap_buffer, MAX_TRAP_LEN, actual_len, true);
1278
1279    local_lib_state = libs;
1280    signal(SIGTRAP, lib_trap_handler);
1281
1282    memcpy((void*) lib_trap_addr_self, trap_buffer, actual_len);   
1283    sw_printf("[%s:%u] - Successfully install lib tracker at 0x%lx\n",
1284             __FILE__, __LINE__, lib_trap_addr_self);
1285 }
1286
1287 bool TrackLibState::updateLibsArch()
1288 {
1289    vsys_info *vsys = getVsysInfo(procstate);
1290    if (!vsys) {
1291       return false;
1292    }
1293    std::stringstream ss;
1294    ss << "[vsyscall-" << procstate->getProcessId() << "]";
1295    LibAddrPair vsyscall_page;
1296    vsyscall_page.first = ss.str();
1297    vsyscall_page.second = vsys->start;
1298    
1299    SymbolReaderFactory *fact = getDefaultSymbolReader();
1300    SymReader *reader = fact->openSymbolReader((char *) vsys->vsys_mem, vsys->end - vsys->start);
1301    if (reader)
1302       LibraryWrapper::registerLibrary(reader, vsyscall_page.first);
1303
1304    std::pair<LibAddrPair, unsigned int> vsyscall_lib_pair;
1305    vsyscall_lib_pair.first = vsyscall_page;
1306    vsyscall_lib_pair.second = static_cast<unsigned int>(vsys->end - vsys->start);
1307    arch_libs.push_back(vsyscall_lib_pair);
1308
1309    return true;
1310 }
1311
1312 #define NUM_VSYS_SIGRETURNS 3
1313 static const char* vsys_sigreturns[] = {
1314    "_sigreturn",
1315    "__kernel_sigreturn",
1316    "__kernel_rt_sigreturn"
1317 };
1318
1319 void SigHandlerStepperImpl::registerStepperGroup(StepperGroup *group)
1320 {
1321    ProcessState *ps = getProcessState();
1322    assert(ps);
1323
1324    LibraryState *libs = getProcessState()->getLibraryTracker();
1325    if (!libs) {
1326       sw_printf("[%s:%u] - Custom library tracker.  Don't know how to"
1327                 " to get libc\n", __FILE__, __LINE__);
1328       return;
1329    }
1330    SymbolReaderFactory *fact = getDefaultSymbolReader();
1331    if (!fact) {
1332       sw_printf("[%s:%u] - Failed to get symbol reader\n", __FILE__, __LINE__);
1333       return;
1334    }
1335
1336    if (!init_libc) {
1337       /**
1338        * Get __restore_rt out of libc
1339        **/
1340       LibAddrPair libc_addr;
1341       Dyninst::SymReader *libc = NULL;
1342       Symbol_t libc_restore;
1343       bool result = libs->getLibc(libc_addr);
1344       if (!result) {
1345          sw_printf("[%s:%u] - Unable to find libc, not registering restore_rt"
1346                    "tracker.\n", __FILE__, __LINE__);
1347       }
1348       if (result) {
1349          init_libc = true;
1350          libc = fact->openSymbolReader(libc_addr.first);
1351          if (!libc) {
1352             sw_printf("[%s:%u] - Unable to open libc, not registering restore_rt\n",
1353                       __FILE__, __LINE__);
1354          }   
1355       }
1356       if (libc) {
1357          libc_restore = libc->getSymbolByName("__restore_rt");
1358          if (!libc->isValidSymbol(libc_restore)) {
1359             sw_printf("[%s:%u] - Unable to find restore_rt in libc\n",
1360                       __FILE__, __LINE__);
1361          }
1362          else {
1363             Dyninst::Address start = libc->getSymbolOffset(libc_restore);
1364             Dyninst::Address end = libc->getSymbolSize(libc_restore) + start;
1365             if (start == end)
1366                end = start + 16; //Estimate--annoying
1367             sw_printf("[%s:%u] - Registering libc restore_rt as at %lx to %lx\n",
1368                       __FILE__, __LINE__, start, end);
1369             group->addStepper(parent_stepper, start, end);
1370          }
1371       }
1372    }
1373
1374    if (!init_libthread) {
1375       /**
1376        * Get __restore_rt out of libpthread
1377        **/
1378       LibAddrPair libpthread_addr;
1379       Dyninst::SymReader *libpthread = NULL;
1380       Symbol_t libpthread_restore;
1381       bool result  = libs->getLibthread(libpthread_addr);
1382       if (!result) {
1383          sw_printf("[%s:%u] - Unable to find libpthread, not registering restore_rt"
1384                    "pthread tracker.\n", __FILE__, __LINE__);
1385       }
1386       if (result) {
1387          libpthread = fact->openSymbolReader(libpthread_addr.first);
1388          if (!libpthread) {
1389             sw_printf("[%s:%u] - Unable to open libc, not registering restore_rt\n",
1390                       __FILE__, __LINE__);
1391          }
1392          init_libthread = true;
1393       }
1394       if (libpthread) {
1395          libpthread_restore = libpthread->getSymbolByName("__restore_rt");
1396          if (!libpthread->isValidSymbol(libpthread_restore)) {
1397             sw_printf("[%s:%u] - Unable to find restore_rt in libpthread\n",
1398                       __FILE__, __LINE__);
1399          }
1400          else {
1401             Dyninst::Address start = libpthread->getSymbolOffset(libpthread_restore);
1402             Dyninst::Address end = libpthread->getSymbolSize(libpthread_restore) + start;
1403             if (start == end)
1404                end = start + 16; //Estimate--annoying
1405             sw_printf("[%s:%u] - Registering libpthread restore_rt as at %lx to %lx\n",
1406                       __FILE__, __LINE__, start, end);
1407             group->addStepper(parent_stepper, start, end);
1408          }
1409       }   
1410    }
1411
1412    /**
1413     * Get symbols out of vsyscall page
1414     **/
1415    vsys_info *vsyscall = getVsysInfo(ps);
1416    if (!vsyscall)
1417    {
1418 #if !defined(arch_x86_64)
1419       sw_printf("[%s:%u] - Odd.  Couldn't find vsyscall page. Signal handler"
1420                 " stepping may not work\n", __FILE__, __LINE__);
1421 #endif
1422    }
1423    else
1424    {
1425       SymReader *vsys_syms = vsyscall->syms;
1426       if (!vsys_syms) {
1427          sw_printf("[%s:%u] - Vsyscall page wasn't parsed\n", __FILE__, __LINE__);
1428       }
1429       else {
1430          for (unsigned i=0; i<NUM_VSYS_SIGRETURNS; i++)
1431          {
1432             Symbol_t sym;
1433             sym = vsys_syms->getSymbolByName(vsys_sigreturns[i]);
1434             if (!vsys_syms->isValidSymbol(sym))
1435                continue;
1436             
1437             Dyninst::Offset offset = vsys_syms->getSymbolOffset(sym);
1438             Dyninst::Address addr;
1439             if (offset < vsyscall->start)
1440                addr = offset + vsyscall->start;
1441             else
1442                addr = offset;
1443             unsigned long size = vsys_syms->getSymbolSize(sym);
1444             if (!size) 
1445                size = ps->getAddressWidth();
1446             
1447             group->addStepper(parent_stepper, addr, addr + size);
1448          }
1449       }
1450    }
1451 }
1452
1453 ThreadState* ThreadState::createThreadState(ProcDebug *parent,
1454                                             Dyninst::THR_ID id,
1455                                             bool already_attached)
1456 {
1457    assert(parent);
1458    Dyninst::THR_ID tid = id;
1459    if (id == NULL_THR_ID) {
1460       tid = (Dyninst::THR_ID) parent->getProcessId();
1461    }
1462    else {
1463       tid = id;
1464    }
1465    
1466    ThreadState *newts = new ThreadState(parent, tid);
1467    sw_printf("[%s:%u] - Creating new ThreadState %p for %d/%d\n",
1468              __FILE__, __LINE__, newts, parent->getProcessId(), tid);
1469    if (!newts || newts->state() == ps_errorstate) {
1470       sw_printf("[%s:%u] - Error creating new thread\n",
1471                 __FILE__, __LINE__);
1472       return NULL;
1473    }
1474    if (already_attached) {
1475       newts->setState(ps_attached_intermediate);
1476    }
1477
1478    std::map<pid_t, int>::iterator previous_event;
1479    previous_event = ProcDebugLinux::unknown_pid_events.find(tid);
1480    if (previous_event != ProcDebugLinux::unknown_pid_events.end()) {
1481       int status = (*previous_event).second;
1482       sw_printf("[%s:%u] - Matched new thread %d with old events with statis %lx\n",
1483                 __FILE__, __LINE__, tid, status);
1484       if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP) {
1485          newts->setState(ps_running);
1486       }
1487       ProcDebugLinux::unknown_pid_events.erase(previous_event);
1488    }
1489
1490    ProcDebug::thread_map_t::iterator i = ProcDebugLinux::all_threads.find(tid);
1491    assert(i == ProcDebugLinux::all_threads.end() || 
1492           (*i).second->state() == ps_exited);
1493    ProcDebugLinux::all_threads[tid] = newts;
1494    parent->threads[tid] = newts;
1495
1496    if (id == NULL_THR_ID) {
1497       //Done with work for initial thread
1498       return newts;
1499    }
1500
1501    bool result;
1502
1503    if (newts->state() == ps_neonatal) {
1504       result = parent->debug_attach(newts);
1505       if (!result && getLastError() == err_procexit) {
1506          sw_printf("[%s:%u] - Thread %d exited before attach\n", 
1507                    __FILE__, __LINE__, tid);
1508          newts->setState(ps_exited);
1509          return NULL;
1510       }
1511       else if (!result) {
1512          sw_printf("[%s:%u] - Unknown error attaching to thread %d\n",
1513                    __FILE__, __LINE__, tid);
1514          newts->setState(ps_errorstate);
1515          return NULL;
1516       }
1517    }
1518    result = parent->debug_waitfor_attach(newts);
1519    if (!result) {
1520       sw_printf("[%s:%u] - Error waiting for attach on %d\n", 
1521                 __FILE__, __LINE__, tid);
1522       return NULL;
1523    }
1524
1525    result = parent->debug_post_attach(newts);
1526    if (!result) {
1527       sw_printf("[%s:%u] - Error in post attach on %d\n",
1528                 __FILE__, __LINE__, tid);
1529       return NULL;
1530    }
1531
1532    result = parent->resume_thread(newts);
1533    if (!result) {
1534       sw_printf("[%s:%u] - Error resuming thread %d\n",
1535                 __FILE__, __LINE__, tid);
1536    }
1537    
1538    return newts;
1539 }
1540
1541 void BottomOfStackStepperImpl::initialize()
1542 {
1543    ProcessState *proc = walker->getProcessState();
1544    assert(proc);
1545
1546    sw_printf("[%s:%u] - Initializing BottomOfStackStepper\n", __FILE__, __LINE__);
1547    
1548    LibraryState *libs = proc->getLibraryTracker();
1549    if (!libs) {
1550       sw_printf("[%s:%u] - Error initing StackBottom.  No library state for process.\n",
1551                 __FILE__, __LINE__);
1552       return;
1553    }
1554    SymbolReaderFactory *fact = getDefaultSymbolReader();
1555    if (!fact) {
1556       sw_printf("[%s:%u] - Failed to get symbol reader\n");
1557       return;
1558    }
1559
1560    if (!aout_init)
1561    {
1562       LibAddrPair aout_addr;
1563       SymReader *aout = NULL;
1564       Symbol_t start_sym;
1565       bool result = libs->getAOut(aout_addr);
1566       if (result) {
1567          aout = fact->openSymbolReader(aout_addr.first);
1568          aout_init = true;
1569       }
1570       if (aout) {
1571          start_sym = aout->getSymbolByName("_start");
1572          if (aout->isValidSymbol(start_sym)) {
1573             Dyninst::Address start = aout->getSymbolOffset(start_sym)+aout_addr.second;
1574             Dyninst::Address end = aout->getSymbolSize(start_sym) + start;
1575             if (start == end)
1576                end = start + 43;
1577             ra_stack_tops.push_back(std::pair<Address, Address>(start, end));
1578          }
1579       }
1580    }
1581
1582    if (!libthread_init)
1583    {
1584       LibAddrPair libthread_addr;
1585       SymReader *libthread = NULL;
1586       Symbol_t clone_sym, startthread_sym;
1587       bool result = libs->getLibthread(libthread_addr);
1588       if (result) {
1589          libthread = fact->openSymbolReader(libthread_addr.first);
1590          libthread_init = true;
1591       }
1592       if (libthread) {
1593          clone_sym = libthread->getSymbolByName("__clone");
1594          if (libthread->isValidSymbol(clone_sym)) {
1595             Dyninst::Address start = libthread->getSymbolOffset(clone_sym) + 
1596                libthread_addr.second;
1597             Dyninst::Address end = libthread->getSymbolSize(clone_sym) + start;
1598             ra_stack_tops.push_back(std::pair<Address, Address>(start, end));
1599          }
1600          startthread_sym = libthread->getSymbolByName("start_thread");
1601          if (libthread->isValidSymbol(startthread_sym)) {
1602             Dyninst::Address start = libthread->getSymbolOffset(startthread_sym) + 
1603                libthread_addr.second;
1604             Dyninst::Address end = libthread->getSymbolSize(startthread_sym) + start;
1605             ra_stack_tops.push_back(std::pair<Address, Address>(start, end));
1606          }
1607       }
1608    }
1609 }
1610
1611 void BottomOfStackStepperImpl::newLibraryNotification(LibAddrPair *, lib_change_t change)
1612 {
1613    if (change == library_unload)
1614       return;
1615    if (!libthread_init || !aout_init) {
1616       initialize();
1617    }
1618 }
1619