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