Initial commit of StackwalkerAPI
[dyninst.git] / stackwalk / src / linux-swk.C
1 /*
2  * Copyright (c) 1996-2007 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
30  */
31
32 #include "stackwalk/h/swk_errors.h"
33 #include "stackwalk/h/symlookup.h"
34 #include "stackwalk/h/walker.h"
35
36 #include "stackwalk/h/procstate.h"
37 #include "stackwalk/src/linux-swk.h"
38
39 #include "common/h/linuxKludges.h"
40 #include "common/h/parseauxv.h"
41
42 #include <string>
43
44 #include <string.h>
45 #include <sys/syscall.h>
46 #include <unistd.h>
47 #include <errno.h>
48 #include <assert.h>
49 #include <signal.h>
50 #include <sys/ptrace.h>
51 #include <sys/types.h>
52 #include <sys/wait.h>
53 #include <fcntl.h>
54
55 using namespace Dyninst;
56 using namespace Dyninst::Stackwalker;
57
58 SymbolLookup *Walker::createDefaultSymLookup(const std::string &exec)
59 {
60    SymbolLookup *new_lookup = new SwkDynSymtab(this, exec);
61    return new_lookup;
62 }
63
64 bool SymbolLookup::lookupLibrary(Address addr, Address &load_addr,
65                                  std::string &out_library)
66 {
67   PID pid = getProcessState()->getProcessId();
68   unsigned maps_size;
69   bool result;
70
71   map_entries *maps = getLinuxMaps((int) pid, maps_size);
72   if (!maps) {
73     sw_printf("[%s:%u] - Unable to look up maps entries for pid %d\n",
74                __FILE__, __LINE__, pid);
75     setLastError(err_procread, "Unable to read /proc/PID/maps for a process");
76     result = false;
77     goto done;
78   }
79
80   unsigned i;
81   signed j;
82   for (i=0; i<maps_size; i++) {
83     if (addr >= maps[i].start && addr < maps[i].end) {
84       out_library = maps[i].path;
85       load_addr = maps[i].start;
86       result = true;
87       sw_printf("[%s:%u] - Found library %s for addr %x\n",
88                  __FILE__, __LINE__, maps[i].path, addr);
89       goto done;
90     }
91   }
92
93   for (j = i-1; j >= 0; j--)
94   {
95     if (maps[i].inode == maps[j].inode)
96       load_addr = maps[j].start;
97   }
98   sw_printf("[%s:%u] - Unable find maps entries for pid %d\n", 
99              __FILE__, __LINE__, pid);
100   setLastError(err_nosymbol, "Unable to find containing library for at address\n");
101   result = false;
102
103  done:
104   if (maps)
105     free(maps);
106   maps = NULL;
107   return result;
108 }
109
110 #ifndef SYS_tkill
111 #define SYS_tkill 238
112 #endif
113
114 static int P_gettid()
115 {
116   static int gettid_not_valid = 0;
117   int result;
118
119   if (gettid_not_valid)
120     return getpid();
121
122   result = syscall((long int) SYS_gettid);
123   if (result == -1 && errno == ENOSYS)
124   {
125     gettid_not_valid = 1;
126     return getpid();
127   }
128   return result;  
129 }
130
131 static bool t_kill(int pid, int sig)
132 {
133   static bool has_tkill = true;
134   int result = 0;
135   sw_printf("[%s:%u] - Sending %d to %d\n", __FILE__, __LINE__, sig, pid);
136   if (has_tkill) {
137      result = syscall(SYS_tkill, pid, sig);
138      if (result == -1 && errno == ENOSYS)
139      {
140         sw_printf("[%s:%d] - Using kill instead of tkill on this system\n", 
141                   __FILE__, __LINE__, sig, pid);
142         has_tkill = false;
143      }
144   }
145   if (!has_tkill) {
146      result = kill(pid, sig);
147   }
148
149   return (result == 0);
150 }
151
152 ProcSelf::ProcSelf()
153 {
154   mypid = getpid();
155 }
156
157 #if defined(cap_sw_catchfaults)
158
159 #include <setjmp.h>
160
161 static bool registered_handler = false;
162 static bool reading_memory = false;
163 sigjmp_buf readmem_jmp;
164
165 void handle_fault(int /*sig*/)
166 {
167    if (!reading_memory) {
168       //The instruction that caused this fault was not from
169       // ProcSelf::readMem.  Restore the SIGSEGV handler, and 
170       // the faulting instruction should restart after we return.
171       fprintf(stderr, "[%s:%u] - Caught segfault that didn't come " \
172               "from stackwalker memory read!", __FILE__, __LINE__);
173       signal(SIGSEGV, SIG_DFL);
174       return;
175    }
176    siglongjmp(readmem_jmp, 1);
177 }
178
179 bool ProcSelf::readMem(void *dest, Address source, size_t size)
180 {
181    if (!registered_handler) {
182       signal(SIGSEGV, handle_fault);
183       registered_handler = true;
184    }
185    reading_memory = true;
186    if (sigsetjmp(readmem_jmp, 1)) {
187       sw_printf("[%s:%u] - Caught fault while reading from %lx to %lx\n", 
188                 __FILE__, __LINE__, source, source + size);
189       setLastError(err_procread, "Could not read from process");
190       return false;
191    }
192    
193    memcpy(dest, (const void *) source, size);
194    reading_memory = false;
195    return true;
196 }
197 #else
198 bool ProcSelf::readMem(void *dest, Address source, size_t size)
199 {
200   memcpy(dest, (const void *) source, size);
201   return true;
202 }
203 #endif
204
205 bool ProcSelf::getThreadIds(std::vector<THR_ID> &threads)
206 {
207   bool result;
208   THR_ID tid;
209
210   result = getDefaultThread(tid);
211   if (!result) {
212     sw_printf("[%s:%u] - Could not read default thread\n",
213                __FILE__, __LINE__);
214     return false;
215   }
216   threads.clear();
217   threads.push_back(tid);
218   return true;
219 }
220
221 bool ProcSelf::getDefaultThread(THR_ID &default_tid)
222 {
223   THR_ID tid = P_gettid();
224   if (tid == -1) {
225     const char *sys_err_msg = strerror(errno);
226     sw_printf("[%s:%u] - gettid syscall failed with %s\n",
227                __FILE__, __LINE__, sys_err_msg);
228     std::string errmsg("gettid syscall failed with ");
229     errmsg += sys_err_msg;
230     setLastError(err_internal, errmsg.c_str());
231     return false;
232   }
233
234   default_tid = tid;
235   return true;
236 }
237
238 DebugEvent ProcDebug::debug_get_event(bool block)
239 {
240    int status = 0;
241    DebugEvent ev;
242    pid_t p;
243
244    sw_printf("[%s:%u] - Calling waitpid\n",__FILE__, __LINE__);
245    int flags = __WALL;
246    if (!block)
247      flags |= WNOHANG;
248    p = waitpid(-1, &status, flags);
249    if (p == -1) {
250       int errnum = errno;
251       sw_printf("[%s:%u] - Unable to wait for debug event: %s\n",
252                 __FILE__, __LINE__, strerror(errnum));
253       if (errnum == EINTR)
254          setLastError(err_interrupt, "System call interrupted");
255       else
256          setLastError(err_internal, "Error calling waitpid");
257       ev.dbg = dbg_err;
258       return ev;
259    }
260    
261    if (p == 0) {
262      sw_printf("[%s:%u] - No debug events available\n", __FILE__, __LINE__);
263      ev.dbg = dbg_noevent;
264      return ev;
265    }
266
267    if (pipe_out != -1)
268    {
269       /*      struct pollfd[1];
270       pollfd[0].fd = pipe_out;
271       pollfd[0].events = POLLIN;
272       pollfd[0].revents = 0;
273       poll(pollfd, 1, 0);*/
274       char c;
275       read(pipe_out, &c, 1);
276    }
277    
278    std::map<PID, ProcDebug *, procdebug_ltint>::iterator i = proc_map.find(p);
279    if (i == proc_map.end())
280    {
281       sw_printf("[%s:%u] - Error, recieved unknown pid %d from waitpid",
282                 __FILE__, __LINE__, p);
283       setLastError(err_internal, "Error calling waitpid");
284       ev.dbg = dbg_err;
285       return ev;
286    }
287    ev.proc = i->second;
288
289    if (WIFEXITED(status)) 
290    {
291       ev.dbg = dbg_exited;
292       ev.data.idata = WEXITSTATUS(status);
293       sw_printf("[%s:%u] - Process %d exited with %d\n", 
294                 __FILE__, __LINE__, p, ev.dbg);
295    }
296    else if (WIFSIGNALED(status))
297    {
298       ev.dbg = dbg_crashed;
299       ev.data.idata = WTERMSIG(status);
300       sw_printf("[%s:%u] - Process %d crashed with %d\n", 
301                 __FILE__, __LINE__, p, ev.dbg);
302    }
303    else if (WIFSTOPPED(status))
304    {
305       ev.dbg = dbg_stopped;
306       ev.data.idata = WSTOPSIG(status);
307       sw_printf("[%s:%u] - Process %d stopped with %d\n",
308                 __FILE__, __LINE__, p, ev.data);
309    }
310    else
311    {
312       sw_printf("[%s:%u] - Process %d had strange return value from waitpid\n",
313                 __FILE__, __LINE__, p);
314       setLastError(err_internal, "Error calling waitpid");
315       ev.dbg = dbg_err;
316    }
317    return ev;
318 }
319
320 bool ProcDebugLinux::debug_handle_event(DebugEvent ev)
321 {
322   bool result;
323
324   switch (ev.dbg)
325   {
326      case dbg_stopped:
327         isRunning = false;
328         
329         if (state == ps_neonatal && ev.data.idata == SIGSTOP) {
330            sw_printf("[%s:%u] - Moving %d to state running\n", 
331                      __FILE__, __LINE__, pid);
332            state = ps_running;
333            return true;
334         }
335         if (state == ps_neonatal && ev.data.idata == SIGTRAP) {
336            sw_printf("[%s:%u] - Moving %d to state running\n", 
337                      __FILE__, __LINE__, pid);
338            state = ps_running;
339            return true;
340         }
341         
342         if (ev.data.idata != SIGSTOP) {
343            result = debug_continue_with(ev.data.idata);
344            if (!result) {
345               sw_printf("[%s:%u] - Debug continue failed on %d with %d\n", 
346                         __FILE__, __LINE__, pid, ev.data.idata);
347               return false;
348            }
349         }
350         return true;
351     case dbg_crashed:
352       sw_printf("[%s:%u] - Handling process crash on %d\n",
353                 __FILE__, __LINE__, pid);
354     case dbg_exited:
355       sw_printf("[%s:%u] - Handling process death on %d\n",
356                 __FILE__, __LINE__, pid);
357       state = ps_exited;
358       return true;
359     case dbg_err:
360     case dbg_noevent:
361     default:
362       sw_printf("[%s:%u] - Unexpectedly handling an error event %d on %d\n", 
363                 __FILE__, __LINE__, ev.dbg, pid);
364       setLastError(err_internal, "Told to handle an unexpected event.");
365       return false;
366   }
367 }
368
369 bool ProcDebugLinux::debug_handle_signal(DebugEvent *ev)
370 {
371    assert(ev->dbg == dbg_stopped);
372    return debug_continue_with(ev->data.idata);
373 }
374
375 bool ProcDebugLinux::debug_attach()
376 {
377    long result;
378    
379    sw_printf("[%s:%u] - Attaching to pid\n", __FILE__, __LINE__, pid);
380    result = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
381    if (result != 0) {
382       int errnum = errno;
383       sw_printf("[%s:%u] - Unable to attach to process %d: %s\n",
384                 __FILE__, __LINE__, pid, strerror(errnum));
385       if (errnum == EPERM)
386          setLastError(err_prem, "Do not have correct premissions to attach " \
387                       "to pid");
388       else if (errnum == ESRCH)
389          setLastError(err_noproc, "The specified process was not found");
390       else {
391          setLastError(err_internal, "DynStackwalker was unable to attach to " \
392                       "the specified process");
393       }
394       return false;
395    }
396    return true;
397 }
398
399 bool ProcDebugLinux::debug_pause() 
400 {
401    bool result;
402
403    result = t_kill(pid, SIGSTOP);
404    if (result != 0) {
405       sw_printf("[%s:%u] - t_kill failed on %d: %s\n", __FILE__, __LINE__,
406                 pid, strerror(errno));
407       setLastError(err_internal, "Could not send signal to process while " \
408                    "stopping");
409       return false;
410    }
411    
412    return true;
413 }
414
415 bool ProcDebugLinux::debug_continue()
416 {
417    return debug_continue_with(0);
418 }
419
420 bool ProcDebugLinux::debug_continue_with(long sig)
421 {
422    long result;
423    assert(!isRunning);
424
425    result = ptrace(PTRACE_CONT, pid, NULL, (void *) sig);
426    if (result != 0)
427    {
428      int errnum = errno;
429       sw_printf("[%s:%u] - Error continuing %d with %d: %s\n",
430                 __FILE__, __LINE__, pid, sig, strerror(errnum));
431       setLastError(err_internal, "Could not continue process");
432       return false;
433    }
434
435    isRunning = true;
436    return true;
437 }
438
439 bool ProcDebugLinux::readMem(void *dest, Address source, size_t size)
440 {
441    unsigned int nbytes = size;
442    const unsigned char *ap = (const unsigned char*) source;
443    unsigned char *dp = (unsigned char*) dest;
444    Address w = 0x0;               /* ptrace I/O buffer */
445    int len = sizeof(long);
446    unsigned cnt;
447    
448    if (!nbytes) {
449       return true;
450    }
451    
452    if ((cnt = ((Address)ap) % len)) {
453       /* Start of request is not aligned. */
454       unsigned char *p = (unsigned char*) &w;
455       
456       /* Read the segment containing the unaligned portion, and
457          copy what was requested to DP. */
458       errno = 0;
459       w = ptrace(PTRACE_PEEKTEXT, pid, (Address) (ap-cnt), w);
460       if (errno) {
461          int errnum = errno;
462          sw_printf("[%s:%u] - PTRACE_PEEKTEXT returned error on %d: %s\n",
463                    __FILE__, __LINE__, pid, strerror(errnum));
464          setLastError(err_procread, "Could not read from process\n");
465          return false;
466       }
467
468       for (unsigned i = 0; i < len-cnt && i < nbytes; i++)
469          dp[i] = p[cnt+i];
470       
471       if (len-cnt >= nbytes) {
472          return true;
473       }
474       
475       dp += len-cnt;
476       ap += len-cnt;
477       nbytes -= len-cnt;
478    }
479    /* Copy aligned portion */
480    while (nbytes >= (u_int)len) {
481       errno = 0;
482       w = ptrace(PTRACE_PEEKTEXT, pid, (Address) ap, 0);
483       if (errno) {
484          int errnum = errno;
485          sw_printf("[%s:%u] - PTRACE_PEEKTEXT returned error on %d: %s\n",
486                    __FILE__, __LINE__, pid, strerror(errnum));
487          setLastError(err_procread, "Could not read from process\n");
488          return false;
489       }
490       memcpy(dp, &w, len);
491       dp += len;
492       ap += len;
493       nbytes -= len;
494    }
495    
496    if (nbytes > 0) {
497       /* Some unaligned data remains */
498       unsigned char *p = (unsigned char *) &w;
499       
500       /* Read the segment containing the unaligned portion, and
501          copy what was requested to DP. */
502       errno = 0;
503       w = ptrace(PTRACE_PEEKTEXT, pid, (Address) ap, 0);
504       if (errno) {
505          int errnum = errno;
506          sw_printf("[%s:%u] - PTRACE_PEEKTEXT returned error on %d: %s\n",
507                    __FILE__, __LINE__, pid, strerror(errnum));
508          setLastError(err_procread, "Could not read from process\n");
509          return false;
510       }
511       for (unsigned i = 0; i < nbytes; i++)
512          dp[i] = p[i];
513    }
514
515    return true;
516 }   
517
518 bool ProcDebugLinux::getThreadIds(std::vector<THR_ID> &threads)
519 {
520    threads.clear();
521    threads.push_back((THR_ID) pid);
522    return true;
523 }
524
525 bool ProcDebugLinux::getDefaultThread(THR_ID &default_tid)
526 {
527    default_tid = (THR_ID) pid;
528    return true;
529 }
530
531 ProcDebugLinux::ProcDebugLinux(PID pid)
532    : ProcDebug(pid),
533      cached_addr_width(0)
534 {
535 }
536
537 ProcDebugLinux::ProcDebugLinux(const std::string &executable, 
538                                const std::vector<std::string> &argv)
539    : ProcDebug(executable, argv),
540      cached_addr_width(0)
541 {
542 }
543
544 ProcDebugLinux::~ProcDebugLinux()
545 {
546 }
547    
548 ProcDebug *ProcDebug::newProcDebug(PID pid)
549 {
550    ProcDebugLinux *pd = new ProcDebugLinux(pid);
551    if (!pd)
552    {
553       sw_printf("[%s:%u] - Error creating new ProcDebug object\n",
554                 __FILE__, __LINE__);
555       return pd;
556    }
557
558    bool result = pd->attach();
559    if (!result || pd->state != ps_running) {
560      pd->state = ps_errorstate;
561      proc_map.erase(pid);
562      sw_printf("[%s:%u] - Error attaching to process %d\n",
563                __FILE__, __LINE__, pid);
564      delete pd;
565      return NULL;
566    }
567
568    return pd;
569 }
570
571 ProcDebug *ProcDebug::newProcDebug(const std::string &executable, 
572                                    const std::vector<std::string> &argv)
573 {
574    ProcDebugLinux *pd = new ProcDebugLinux(executable, argv);
575    if (!pd)
576    {
577       sw_printf("[%s:%u] - Error creating new ProcDebug object\n",
578                 __FILE__, __LINE__);
579       return NULL;
580    }
581
582    bool result = pd->create(executable, argv);
583    if (!result || pd->state != ps_running)
584    {
585      pd->state = ps_errorstate;
586      proc_map.erase(pd->pid);
587      sw_printf("[%s:%u] - Error attaching to process %d\n",
588                __FILE__, __LINE__, pd->pid);
589      delete pd;
590      return NULL;
591    }
592
593    return pd;   
594 }
595
596
597 void chld_handler(int)
598 {
599    write(ProcDebug::pipe_in, "s", 1);
600 }
601
602 int ProcDebug::getNotificationFD()
603 {
604    static bool registered_handler = false;
605    int filedes[2], result;
606    if (!registered_handler) 
607    {
608       signal(SIGCHLD, chld_handler);
609       result = pipe(filedes);
610       if (result == -1)
611       {
612          int errnum = errno;
613          sw_printf("[%s:%u] - Could not create pipe: %s\n",
614                    __FILE__, __LINE__, strerror(errnum));
615          setLastError(err_internal, "Could not create pipe for notificationFD");
616          return -1;
617       }
618       pipe_out = filedes[0];
619       pipe_in = filedes[1];
620
621       result = fcntl(pipe_out, F_GETFL);
622       if (result != -1)
623       {
624          result = fcntl(pipe_out, F_SETFL, result | O_NONBLOCK);
625       }
626       if (result == -1)
627       {
628          int errnum = errno;
629          sw_printf("[%s:%u] - Could not set fcntl flags: %s\n",
630                    __FILE__, __LINE__, strerror(errnum));
631          setLastError(err_internal, "Could not set pipe properties");
632          return -1;
633       }
634       registered_handler = true;
635    }
636    return pipe_out;
637 }
638
639 bool ProcDebugLinux::debug_create(const std::string &executable, 
640                                   const std::vector<std::string> &argv)
641 {
642    pid = fork();
643    if (pid == -1)
644    {
645       int errnum = errno;
646       sw_printf("[%s:%u] - Could not fork new process for %s: %s\n",
647                 __FILE__, __LINE__, executable.c_str(), strerror(errnum));
648       setLastError(err_internal, "Unable to fork new process");
649       return false;
650    }
651
652    if (pid)
653    {
654       //Parent
655    }
656    else
657    {
658       //Child
659       int result = ptrace(PTRACE_TRACEME, 0, 0, 0);
660       unsigned i;
661       if (result == -1)
662       {
663          sw_printf("[%s:%u] - Failed to execute a PTRACE_TRACME.  Odd.\n",
664                    __FILE__, __LINE__);
665          setLastError(err_internal, "Unable to debug trace new process");
666          exit(-1);
667       }
668
669       typedef const char * const_str;
670       const_str *new_argv = (const_str *) malloc((argv.size()+2) * sizeof(char *));
671       new_argv[0] = executable.c_str();
672       for (i=1; i<argv.size()+1; i++) {
673          new_argv[i] = argv[i-1].c_str();
674       }
675       new_argv[i+1] = (char *) NULL;
676       
677       result = execv(executable.c_str(), const_cast<char * const*>(new_argv));
678       int errnum = errno;         
679       sw_printf("[%s:%u] - Failed to exec %s: %s\n", __FILE__, __LINE__, 
680                 executable.c_str(), strerror(errnum));
681       if (errnum == ENOENT)
682          setLastError(err_nofile, "No such file");
683       if (errnum == EPERM || errnum == EACCES)
684          setLastError(err_prem, "Premission denied");
685       else
686          setLastError(err_internal, "Unable to exec process");
687       exit(-1);
688    }
689    return true;
690 }