"Fossies" - the Fresh Open Source Software Archive

Member "heaplayers-351/allocators/vam/tools/memtrace.h" (16 Jan 2006, 88534 Bytes) of package /linux/misc/old/heaplayers_3_5_1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "memtrace.h" see the Fossies "Dox" file reference documentation.

    1 // -*- C++ -*-
    2 
    3 #ifndef _MEMTRACE_H_
    4 #define _MEMTRACE_H_
    5 
    6 #include <dlfcn.h>
    7 #include <fcntl.h>
    8 #include <grp.h>
    9 #include <sched.h>
   10 #include <signal.h>
   11 #include <stdio.h>
   12 #include <stdlib.h>
   13 #include <time.h>
   14 #include <utime.h>
   15 #include <unistd.h>
   16 #include <attr/xattr.h>
   17 //#include <linux/aio.h>
   18 //#include <linux/futex.h>
   19 #include <linux/unistd.h>
   20 #include <linux/sysctl.h>
   21 #include <linux/reboot.h>
   22 #include <sys/epoll.h>
   23 #include <sys/ipc.h>
   24 #include <sys/mman.h>
   25 #include <sys/mount.h>
   26 #include <sys/msg.h>
   27 #include <sys/poll.h>
   28 #include <sys/resource.h>
   29 #include <sys/select.h>
   30 #include <sys/sendfile.h>
   31 #include <sys/shm.h>
   32 #include <sys/socket.h>
   33 #include <sys/stat.h>
   34 #include <sys/time.h>
   35 #include <sys/types.h>
   36 #include <sys/uio.h>
   37 #include <sys/utsname.h>
   38 #include <sys/vfs.h>
   39 #include <sys/wait.h>
   40 
   41 #include <map>
   42 #include <new>
   43 
   44 #include "heaplayers.h"
   45 //#include "vamcommon.h"
   46 // extract the stuff we need from vamcommon.h
   47 #include <stdarg.h>
   48 #define PAGE_SHIFT      12
   49 #define PAGE_SIZE       (1UL << PAGE_SHIFT)
   50 #define PAGE_MASK       (~(PAGE_SIZE-1))
   51 #define BUF_SZ 1000
   52 
   53 #define LOG_PAGE_ACCESS     1
   54 #define PRINT_TIMESTAMP     0
   55 #define UNPROTECTED_SIZE    128         // window size of unprotected heap pages
   56 
   57 
   58 // PosixRecursiveLockType: recursive lock
   59 class PosixRecursiveLockType {
   60 
   61 public:
   62 
   63     PosixRecursiveLockType() {
   64         pthread_mutexattr_t attr;
   65         pthread_mutexattr_init(&attr);
   66         pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
   67         pthread_mutex_init(&mutex, &attr);
   68     }
   69   
   70     ~PosixRecursiveLockType() {
   71         pthread_mutex_destroy(&mutex);
   72     }
   73   
   74     void lock() {
   75         pthread_mutex_lock(&mutex);
   76     }
   77   
   78     void unlock() {
   79         pthread_mutex_unlock(&mutex);
   80     }
   81   
   82 private:
   83 
   84     pthread_mutex_t mutex;
   85 
   86 };  // end of class PosixRecursiveLockType
   87 
   88 
   89 struct PageCmp {
   90     bool operator()(const void * a, const void * b) const {
   91         return (size_t) a < (size_t) b;
   92     }
   93 };
   94 class MyMapHeap : public HL::OneHeap<HL::FreelistHeap<HL::StaticHeap<4 * 1024 * 1024> > > {};
   95 typedef pair<const void *, unsigned int> PageStatusPair;
   96 typedef map<const void *, unsigned int, PageCmp, HL::STLAllocator<PageStatusPair, MyMapHeap> > PageStatusMap;
   97 
   98 
   99 class MemTracer {
  100 
  101 public:
  102 
  103     void * calloc(size_t nmemb, size_t size) {
  104         MemTracerLock l(_lock);
  105 
  106         // deny memory allocation from dlsym, it'll use static buffer
  107         if (_in_dlsym)
  108             return NULL;
  109 
  110         if (_real_calloc == NULL)
  111             init_all();
  112 
  113         void * rv = (*_real_calloc)(nmemb, size);
  114 
  115         return rv;
  116     }
  117 
  118     void * malloc(size_t size) {
  119         MemTracerLock l(_lock);
  120 
  121         if (_real_malloc == NULL)
  122             init_all();
  123 
  124         void * rv = (*_real_malloc)(size);
  125 
  126         return rv;
  127     }
  128 
  129     void free(void * ptr) {
  130         MemTracerLock l(_lock);
  131 
  132         if (_real_free == NULL)
  133             init_all();
  134 
  135         (*_real_free)(ptr);
  136     }
  137 
  138     void * realloc(void * ptr, size_t size) {
  139         MemTracerLock l(_lock);
  140 
  141         if (_real_realloc == NULL)
  142             init_all();
  143 
  144         void * rv = (*_real_realloc)(ptr, size);
  145 
  146         return rv;
  147     }
  148 
  149     int brk(void * end_data_segment) {
  150         MemTracerLock l(_lock);
  151 
  152         if (_real_brk == NULL)
  153             init_all();
  154 
  155         int rv = (*_real_brk)(end_data_segment);
  156         dbprintf("brk(%p) returned %d\n", end_data_segment, rv);
  157         assert(rv == 0);
  158 
  159         if (rv == 0) {
  160             handleNewBreak((char *) end_data_segment);
  161         }
  162 
  163         return rv;
  164     }
  165 
  166     void * sbrk(intptr_t increment) {
  167         MemTracerLock l(_lock);
  168 
  169         if (_real_sbrk == NULL)
  170             init_all();
  171 
  172         void * rv = (*_real_sbrk)(increment);
  173         dbprintf("sbrk(%d) returned %p\n", increment, rv);
  174         assert(rv == currentBreak);
  175 
  176         if (rv == currentBreak) {
  177             handleNewBreak(currentBreak + increment);
  178         }
  179 
  180         return rv;
  181     }
  182 
  183     void * mmap(void * start, size_t length, int prot, int flags, int fd, off_t offset) {
  184         MemTracerLock l(_lock);
  185 
  186         if (_real_mmap == NULL)
  187             init_all();
  188 
  189         void * rv = (*_real_mmap)(start, length, prot, flags, fd, offset);
  190         dbprintf("mmap(%p, %x, %x, %x, %d, %x) returned %p\n", start, length, prot, flags, fd, offset, rv);
  191         assert(((size_t) rv & ~PAGE_MASK) == 0);
  192 
  193         if (rv != NULL && length != 0x801000) {
  194             unsigned int page_status;
  195             char tag;
  196 
  197             if (flags & MAP_ANONYMOUS) {
  198                 page_status = PAGE_MMAP_ANON;
  199                 tag = 'A';
  200             }
  201             else {
  202                 if (flags & MAP_PRIVATE) {
  203                     page_status = PAGE_MMAP_PRIVATE;
  204                     tag = 'P';
  205                 }
  206                 else {
  207                     assert(flags & MAP_SHARED);
  208                     page_status = PAGE_MMAP_SHARED;
  209                     tag = 'S';
  210                 }
  211             }
  212 
  213             page_status |= PAGE_ON_DEMAND;
  214 
  215             if (prot & PROT_READ)
  216                 page_status |= PAGE_ORIG_READABLE;
  217             if (prot & PROT_WRITE)
  218                 page_status |= PAGE_ORIG_WRITABLE;
  219 
  220             length = (length + PAGE_SIZE - 1) & PAGE_MASK;
  221 
  222             // mprotect the pages to trap future access
  223             if (_real_mprotect == NULL)
  224                 init_all();
  225 
  226             int rc = (*_real_mprotect)(rv, length, PROT_NONE);
  227             assert(rc == 0);
  228 
  229             size_t mapped = 0;
  230             while (mapped < length) {
  231                 void * page= (char *) rv + mapped;
  232                 trace_printf("%c 0x%08x\n", tag, page);
  233 
  234                 assert(_page_status_map.find(page) == _page_status_map.end());
  235                 _page_status_map[page] = page_status;
  236 
  237                 mapped += PAGE_SIZE;
  238             }
  239 
  240             currentAllocatedMmap += length;
  241             currentMmapUntouched += length;
  242             if (currentAllocatedMmap + currentAllocatedSbrk > maxAllocated) {
  243                 maxAllocated = currentAllocatedMmap + currentAllocatedSbrk;
  244             }
  245         }
  246 
  247         return rv;
  248     }
  249 
  250     int munmap(void * start, size_t length) {
  251         MemTracerLock l(_lock);
  252 
  253         if (_real_munmap == NULL)
  254             init_all();
  255 
  256         int rv = (*_real_munmap)(start, length);
  257         dbprintf("munmap(%p, %x) returned %d\n", start, length, rv);
  258 
  259         if (rv == 0 && length != 0x801000) {
  260             length = (length + PAGE_SIZE - 1) & PAGE_MASK;
  261 
  262             size_t unmapped = 0;
  263             while (unmapped < length) {
  264                 void * page = (char *) start + unmapped;
  265                 trace_printf("U 0x%08x\n", page);
  266 
  267                 // find and remove the page in the map
  268                 PageStatusMap::iterator i = _page_status_map.find(page);
  269                 assert(i != _page_status_map.end());
  270 
  271                 if (i != _page_status_map.end()) {
  272                     unsigned int page_status = (*i).second;
  273 
  274                     switch (page_status & PAGE_MAPPING_MASK) {
  275                     case PAGE_MMAP_ANON:
  276                     case PAGE_MMAP_PRIVATE:
  277                     case PAGE_MMAP_SHARED:
  278                         break;
  279                     default:
  280                         assert(false);
  281                     }
  282 
  283                     switch (page_status & PAGE_STATUS_MASK) {
  284                     case PAGE_ON_DEMAND:
  285                         currentMmapUntouched -= PAGE_SIZE;
  286                         assert(currentMmapUntouched >= 0);
  287                         break;
  288                     case PAGE_DISCARDED:
  289                         currentMmapDiscarded -= PAGE_SIZE;
  290                         break;
  291                     case PAGE_IN_MEMORY:
  292                         break;
  293                     default:
  294                         assert(false);
  295                     }
  296 
  297                     _page_status_map.erase(i);
  298                 }
  299 
  300                 unmapped += PAGE_SIZE;
  301             }
  302 
  303             currentAllocatedMmap -= length;
  304 
  305             // remove these in the unprotected window
  306             removePageRangeUnprotectedWindow((size_t) start, length);
  307         }
  308 
  309         return rv;
  310     }
  311 
  312     int madvise(void * start, size_t length, int advice) {
  313         MemTracerLock l(_lock);
  314 
  315         if (_real_madvise == NULL)
  316             init_all();
  317 
  318         int rv = (*_real_madvise)(start, length, advice);
  319         dbprintf("madvise(%p, %x, %d) returned %d\n", start, length, advice, rv);
  320 
  321         if (rv == 0 && advice == MADV_DONTNEED) {
  322             length = (length + PAGE_SIZE - 1) & PAGE_MASK;
  323 
  324             // mprotect the pages to trap future access
  325             if (_real_mprotect == NULL)
  326                 init_all();
  327 
  328             int rc = (*_real_mprotect)(start, length, PROT_NONE);
  329             assert(rc == 0);
  330 
  331             size_t advised = 0;
  332             while (advised < length) {
  333                 void * page = (char *) start + advised;
  334                 trace_printf("D 0x%08x\n", page);
  335 
  336                 // find the page in the map and change its status
  337                 PageStatusMap::iterator i = _page_status_map.find(page);
  338                 assert(i != _page_status_map.end());
  339 
  340                 if (i != _page_status_map.end()) {
  341                     unsigned int page_status = (*i).second;
  342 
  343                     switch (page_status & PAGE_STATUS_MASK) {
  344                     case PAGE_ON_DEMAND:
  345                     case PAGE_DISCARDED:
  346                         break;
  347                     case PAGE_IN_MEMORY:
  348                         switch (page_status & PAGE_MAPPING_MASK) {
  349                         case PAGE_SBRK_ANON:
  350                             currentSbrkDiscarded += PAGE_SIZE;
  351                             break;
  352                         case PAGE_MMAP_ANON:
  353                         case PAGE_MMAP_PRIVATE:
  354                         case PAGE_MMAP_SHARED:
  355                             currentMmapDiscarded += PAGE_SIZE;
  356                             break;
  357                         default:
  358                             assert(false);
  359                         }
  360                         page_status ^= PAGE_IN_MEMORY | PAGE_DISCARDED;
  361                         break;
  362                     default:
  363                         assert(false);
  364                     }
  365 
  366                     page_status &= ~PAGE_CURR_PROT_MASK;
  367                     (*i).second = page_status;
  368                 }
  369 
  370                 advised += PAGE_SIZE;
  371             }
  372 
  373             // remove these in the unprotected window
  374             removePageRangeUnprotectedWindow((size_t) start, length);
  375         }
  376 
  377         return rv;
  378     }
  379 
  380     int mprotect(void * addr, size_t len, int prot) {
  381         MemTracerLock l(_lock);
  382 
  383         if (_real_mprotect == NULL)
  384             init_all();
  385 
  386         int rv = (*_real_mprotect)(addr, len, prot);
  387         dbprintf("mprotect(%p, %x, %x) returned %d\n", addr, len, prot, rv);
  388         assert(rv == 0);
  389 
  390         if (rv == 0) {
  391             len = (len + PAGE_SIZE - 1) & PAGE_MASK;
  392 
  393             // mprotect the pages to trap future access
  394             int rc = (*_real_mprotect)(addr, len, PROT_NONE);
  395             assert(rc == 0);
  396 
  397             size_t mprotected = 0;
  398             while (mprotected < len) {
  399                 void * page = (char *) addr + mprotected;
  400 
  401                 // find the page in the map and change it status
  402                 PageStatusMap::iterator i = _page_status_map.find(page);
  403 
  404                 if (i != _page_status_map.end()) {
  405                     unsigned int page_status = (*i).second;
  406                     page_status &= ~(PAGE_ORIG_PROT_MASK | PAGE_CURR_PROT_MASK);
  407 
  408                     if (prot & PROT_READ)
  409                         page_status |= PAGE_ORIG_READABLE;
  410                     if (prot & PROT_WRITE)
  411                         page_status |= PAGE_ORIG_WRITABLE;
  412 
  413                     (*i).second = page_status;
  414                 }
  415 
  416                 mprotected += PAGE_SIZE;
  417             }
  418         }
  419 
  420         return rv;
  421     }
  422 
  423     sighandler_t signal(int signum, sighandler_t handler) {
  424         MemTracerLock l(_lock);
  425 
  426         if (_real_signal == NULL)
  427             init_all();
  428 
  429         sighandler_t rv;
  430 
  431         // we can't let user SIGSEGV handler get control
  432         if (signum == SIGSEGV) {
  433             assert(_stored_segv_handler == NULL || _stored_segv_sigaction == NULL);
  434 
  435             if (_stored_segv_handler != NULL)
  436                 rv = _stored_segv_handler;
  437             else {
  438                 rv = (sighandler_t) _stored_segv_sigaction;
  439                 _stored_segv_sigaction = NULL;
  440             }
  441 
  442             _stored_segv_handler = handler;
  443         }
  444         else
  445             rv = (*_real_signal)(signum, handler);
  446 
  447         dbprintf("signal(%d, %p) returned %p\n", signum, handler, rv);
  448         return rv;
  449     }
  450 
  451     int sigaction(int signum, const struct sigaction * act, struct sigaction * oldact) {
  452         MemTracerLock l(_lock);
  453 
  454         if (_real_sigaction == NULL)
  455             init_all();
  456 
  457         int rv;
  458 
  459         // we can't let user SIGSEGV handler get control
  460         if (signum == SIGSEGV) {
  461             assert(_stored_segv_handler == NULL || _stored_segv_sigaction == NULL);
  462 
  463             if (oldact != NULL) {
  464                 memset(oldact, 0, sizeof(*oldact));
  465 
  466                 if (_stored_segv_handler != NULL) {
  467                     oldact->sa_handler = _stored_segv_handler;
  468                 }
  469                 else {
  470                     oldact->sa_sigaction = _stored_segv_sigaction;
  471                 }
  472             }
  473 
  474             if (act != NULL) {
  475                 if (act->sa_flags & SA_SIGINFO) {
  476                     _stored_segv_sigaction = act->sa_sigaction;
  477                     _stored_segv_handler = NULL;
  478                 }
  479                 else {
  480                     _stored_segv_handler = act->sa_handler;
  481                     _stored_segv_sigaction = NULL;
  482                 }
  483             }
  484 
  485             rv = 0;
  486         }
  487         else {
  488             bool need_to_reprotect1 = unprotectBuf(act, sizeof(*act));
  489             bool need_to_reprotect2 = unprotectBuf(oldact, sizeof(*oldact));
  490 
  491             rv = (*_real_sigaction)(signum, act, oldact);
  492 
  493             if (need_to_reprotect1)
  494                 reprotectBuf(act, sizeof(*act));
  495             if (need_to_reprotect2)
  496                 reprotectBuf(oldact, sizeof(*oldact));
  497         }
  498 
  499         dbprintf("sigaction(%d, %p, %p) returned %d\n", signum, act, oldact, rv);
  500 //      assert(rv == 0);
  501 
  502         return rv;
  503     }
  504 /*
  505     void exit(int status) {
  506         MemTracerLock l(_lock);
  507 
  508         if (_real_exit == NULL)
  509             init_all();
  510 
  511         dbprintf("Current allocated with mmap = %d\n", currentAllocatedMmap);
  512         dbprintf("Current allocated with sbrk = %d\n", currentAllocatedSbrk);
  513         dbprintf("Max allocated overall = %d\n", maxAllocated);
  514 
  515         (*_real_exit)(status);
  516     }
  517 */
  518     time_t time(time_t * t) {
  519         if (_real_time == NULL)
  520             init_all();
  521 
  522         bool need_to_reprotect = unprotectBuf(t, sizeof(*t));
  523 
  524         time_t rv = (*_real_time)(t);
  525 
  526         if (need_to_reprotect)
  527             reprotectBuf(t, sizeof(*t));
  528 
  529         return rv;
  530     }
  531 
  532     int stime(const time_t * t) {
  533         if (_real_stime == NULL)
  534             init_all();
  535 
  536         bool need_to_reprotect = unprotectBuf(t, sizeof(*t));
  537 
  538         int rv = (*_real_stime)(t);
  539 
  540         if (need_to_reprotect)
  541             reprotectBuf(t, sizeof(*t));
  542 
  543         return rv;
  544     }
  545 
  546     int gettimeofday(struct timeval * tv, struct timezone * tz) {
  547         if (_real_gettimeofday == NULL)
  548             init_all();
  549 
  550         bool need_to_reprotect1 = unprotectBuf(tv, sizeof(*tv));
  551         bool need_to_reprotect2 = unprotectBuf(tz, sizeof(*tz));
  552 
  553         int rv = (*_real_gettimeofday)(tv, tz);
  554         dbprintf("gettimeofday(%p, %p) returned %d\n", tv, tz, rv);
  555 
  556         if (need_to_reprotect1)
  557             reprotectBuf(tv, sizeof(*tv));
  558         if (need_to_reprotect2)
  559             reprotectBuf(tz, sizeof(*tz));
  560 
  561         return rv;
  562     }
  563 
  564     int settimeofday(const struct timeval * tv, const struct timezone * tz) {
  565         if (_real_settimeofday == NULL)
  566             init_all();
  567 
  568         bool need_to_reprotect1 = unprotectBuf(tv, sizeof(*tv));
  569         bool need_to_reprotect2 = unprotectBuf(tz, sizeof(*tz));
  570 
  571         int rv = (*_real_settimeofday)(tv, tz);
  572 
  573         if (need_to_reprotect1)
  574             reprotectBuf(tv, sizeof(*tv));
  575         if (need_to_reprotect2)
  576             reprotectBuf(tz, sizeof(*tz));
  577 
  578         return rv;
  579     }
  580 
  581     int getresuid(uid_t * ruid, uid_t * euid, uid_t * suid) {
  582         if (_real_getresuid == NULL)
  583             init_all();
  584 
  585         bool need_to_reprotect1 = unprotectBuf(ruid, sizeof(*ruid));
  586         bool need_to_reprotect2 = unprotectBuf(euid, sizeof(*euid));
  587         bool need_to_reprotect3 = unprotectBuf(suid, sizeof(*suid));
  588 
  589         int rv = (*_real_getresuid)(ruid, euid, suid);
  590 
  591         if (need_to_reprotect1)
  592             reprotectBuf(ruid, sizeof(*ruid));
  593         if (need_to_reprotect2)
  594             reprotectBuf(euid, sizeof(*euid));
  595         if (need_to_reprotect3)
  596             reprotectBuf(suid, sizeof(*suid));
  597 
  598         return rv;
  599     }
  600 
  601     int getresgid(gid_t * rgid, gid_t * egid, gid_t * sgid) {
  602         if (_real_getresgid == NULL)
  603             init_all();
  604 
  605         bool need_to_reprotect1 = unprotectBuf(rgid, sizeof(*rgid));
  606         bool need_to_reprotect2 = unprotectBuf(egid, sizeof(*egid));
  607         bool need_to_reprotect3 = unprotectBuf(sgid, sizeof(*sgid));
  608 
  609         int rv = (*_real_getresgid)(rgid, egid, sgid);
  610 
  611         if (need_to_reprotect1)
  612             reprotectBuf(rgid, sizeof(*rgid));
  613         if (need_to_reprotect2)
  614             reprotectBuf(egid, sizeof(*egid));
  615         if (need_to_reprotect3)
  616             reprotectBuf(sgid, sizeof(*sgid));
  617 
  618         return rv;
  619     }
  620 
  621     int sigpending(sigset_t * set) {
  622         if (_real_sigpending == NULL)
  623             init_all();
  624 
  625         bool need_to_reprotect = unprotectBuf(set, sizeof(*set));
  626 
  627         int rv = (*_real_sigpending)(set);
  628 
  629         if (need_to_reprotect)
  630             reprotectBuf(set, sizeof(*set));
  631 
  632         return rv;
  633     }
  634 
  635     int sigprocmask(int how, const sigset_t * set, sigset_t * oldset) {
  636         if (_real_sigprocmask == NULL)
  637             init_all();
  638 
  639         bool need_to_reprotect1 = unprotectBuf(set, sizeof(*set));
  640         bool need_to_reprotect2 = unprotectBuf(oldset, sizeof(*oldset));
  641 
  642         int rv = (*_real_sigprocmask)(how, set, oldset);
  643 
  644         if (need_to_reprotect1)
  645             reprotectBuf(set, sizeof(*set));
  646         if (need_to_reprotect2)
  647             reprotectBuf(oldset, sizeof(*oldset));
  648 
  649         return rv;
  650     }
  651 
  652     int sched_setscheduler(pid_t pid, int policy, const struct sched_param * p) {
  653         if (_real_sched_setscheduler == NULL)
  654             init_all();
  655 
  656         bool need_to_reprotect = unprotectBuf(p, sizeof(*p));
  657 
  658         int rv = (*_real_sched_setscheduler)(pid, policy, p);
  659 
  660         if (need_to_reprotect)
  661             reprotectBuf(p, sizeof(*p));
  662 
  663         return rv;
  664     }
  665 
  666     int sched_setparam(pid_t pid, const struct sched_param * p) {
  667         if (_real_sched_setparam == NULL)
  668             init_all();
  669 
  670         bool need_to_reprotect = unprotectBuf(p, sizeof(*p));
  671 
  672         int rv = (*_real_sched_setparam)(pid, p);
  673 
  674         if (need_to_reprotect)
  675             reprotectBuf(p, sizeof(*p));
  676 
  677         return rv;
  678     }
  679 
  680     int sched_getparam(pid_t pid, struct sched_param * p) {
  681         if (_real_sched_getparam == NULL)
  682             init_all();
  683 
  684         bool need_to_reprotect = unprotectBuf(p, sizeof(*p));
  685 
  686         int rv = (*_real_sched_getparam)(pid, p);
  687 
  688         if (need_to_reprotect)
  689             reprotectBuf(p, sizeof(*p));
  690 
  691         return rv;
  692     }
  693 
  694     pid_t wait(int * status) {
  695         if (_real_wait == NULL)
  696             init_all();
  697 
  698         bool need_to_reprotect = unprotectBuf(status, sizeof(*status));
  699 
  700         pid_t rv = (*_real_wait)(status);
  701 
  702         if (need_to_reprotect)
  703             reprotectBuf(status, sizeof(*status));
  704 
  705         return rv;
  706     }
  707 
  708     pid_t wait3(int * status, int options, struct rusage * rusage) {
  709         if (_real_wait3 == NULL)
  710             init_all();
  711 
  712         bool need_to_reprotect1 = unprotectBuf(status, sizeof(*status));
  713         bool need_to_reprotect2 = unprotectBuf(rusage, sizeof(*rusage));
  714 
  715         pid_t rv = (*_real_wait3)(status, options, rusage);
  716 
  717         if (need_to_reprotect1)
  718             reprotectBuf(status, sizeof(*status));
  719         if (need_to_reprotect2)
  720             reprotectBuf(rusage, sizeof(*rusage));
  721 
  722         return rv;
  723     }
  724 
  725     pid_t wait4(pid_t pid, int * status, int options, struct rusage * rusage) {
  726         if (_real_wait4 == NULL)
  727             init_all();
  728 
  729         bool need_to_reprotect1 = unprotectBuf(status, sizeof(*status));
  730         bool need_to_reprotect2 = unprotectBuf(rusage, sizeof(*rusage));
  731 
  732         pid_t rv = (*_real_wait4)(pid, status, options, rusage);
  733 
  734         if (need_to_reprotect1)
  735             reprotectBuf(status, sizeof(*status));
  736         if (need_to_reprotect2)
  737             reprotectBuf(rusage, sizeof(*rusage));
  738 
  739         return rv;
  740     }
  741 
  742     int waitid(idtype_t idtype, id_t id, siginfo_t * infop, int options) {
  743         if (_real_waitid == NULL)
  744             init_all();
  745 
  746         bool need_to_reprotect = unprotectBuf(infop, sizeof(*infop));
  747 
  748         int rv = (*_real_waitid)(idtype, id, infop, options);
  749 
  750         if (need_to_reprotect)
  751             reprotectBuf(infop, sizeof(*infop));
  752 
  753         return rv;
  754     }
  755 
  756     pid_t waitpid(pid_t pid, int * status, int options) {
  757         if (_real_waitpid == NULL)
  758             init_all();
  759 
  760         bool need_to_reprotect = unprotectBuf(status, sizeof(*status));
  761 
  762         pid_t rv = (*_real_waitpid)(pid, status, options);
  763 
  764         if (need_to_reprotect)
  765             reprotectBuf(status, sizeof(*status));
  766 
  767         return rv;
  768     }
  769 
  770     int statfs(const char * path, struct statfs * buf) {
  771         if (_real_statfs == NULL)
  772             init_all();
  773 
  774         size_t len = strlen(path);
  775         bool need_to_reprotect1 = unprotectBuf(path, len);
  776         bool need_to_reprotect2 = unprotectBuf(buf, sizeof(*buf));
  777 
  778         int rv = (*_real_statfs)(path, buf);
  779 
  780         if (need_to_reprotect1)
  781             reprotectBuf(path, len);
  782         if (need_to_reprotect2)
  783             reprotectBuf(buf, sizeof(*buf));
  784 
  785         return rv;
  786     }
  787 
  788     int statfs64(const char * path, struct statfs64 * buf) {
  789         if (_real_statfs64 == NULL)
  790             init_all();
  791 
  792         size_t len = strlen(path);
  793         bool need_to_reprotect1 = unprotectBuf(path, len);
  794         bool need_to_reprotect2 = unprotectBuf(buf, sizeof(*buf));
  795 
  796         int rv = (*_real_statfs64)(path, buf);
  797 
  798         if (need_to_reprotect1)
  799             reprotectBuf(path, len);
  800         if (need_to_reprotect2)
  801             reprotectBuf(buf, sizeof(*buf));
  802 
  803         return rv;
  804     }
  805 
  806     int fstatfs(int fd, struct statfs * buf) {
  807         if (_real_fstatfs == NULL)
  808             init_all();
  809 
  810         bool need_to_reprotect = unprotectBuf(buf, sizeof(*buf));
  811 
  812         int rv = (*_real_fstatfs)(fd, buf);
  813 
  814         if (need_to_reprotect)
  815             reprotectBuf(buf, sizeof(*buf));
  816 
  817         return rv;
  818     }
  819 
  820     int fstatfs64(int fd, struct statfs64 * buf) {
  821         if (_real_fstatfs64 == NULL)
  822             init_all();
  823 
  824         bool need_to_reprotect = unprotectBuf(buf, sizeof(*buf));
  825 
  826         int rv = (*_real_fstatfs64)(fd, buf);
  827 
  828         if (need_to_reprotect)
  829             reprotectBuf(buf, sizeof(*buf));
  830 
  831         return rv;
  832     }
  833 
  834     int link(const char * oldpath, const char * newpath) {
  835         if (_real_link == NULL)
  836             init_all();
  837 
  838         size_t len1 = strlen(oldpath);
  839         size_t len2 = strlen(newpath);
  840         bool need_to_reprotect1 = unprotectBuf(oldpath, len1);
  841         bool need_to_reprotect2 = unprotectBuf(newpath, len2);
  842 
  843         int rv = (*_real_link)(oldpath, newpath);
  844 
  845         if (need_to_reprotect1)
  846             reprotectBuf(oldpath, len1);
  847         if (need_to_reprotect2)
  848             reprotectBuf(newpath, len2);
  849 
  850         return rv;
  851     }
  852 
  853     int symlink(const char * oldpath, const char * newpath) {
  854         if (_real_symlink == NULL)
  855             init_all();
  856 
  857         size_t len1 = strlen(oldpath);
  858         size_t len2 = strlen(newpath);
  859         bool need_to_reprotect1 = unprotectBuf(oldpath, len1);
  860         bool need_to_reprotect2 = unprotectBuf(newpath, len2);
  861 
  862         int rv = (*_real_symlink)(oldpath, newpath);
  863 
  864         if (need_to_reprotect1)
  865             reprotectBuf(oldpath, len1);
  866         if (need_to_reprotect2)
  867             reprotectBuf(newpath, len2);
  868 
  869         return rv;
  870     }
  871 
  872     int unlink(const char * pathname) {
  873         if (_real_unlink == NULL)
  874             init_all();
  875 
  876         size_t len = strlen(pathname);
  877         bool need_to_reprotect = unprotectBuf(pathname, len);
  878 
  879         int rv = (*_real_unlink)(pathname);
  880 
  881         if (need_to_reprotect)
  882             reprotectBuf(pathname, len);
  883 
  884         return rv;
  885     }
  886 
  887     int rename(const char * oldpath, const char * newpath) {
  888         if (_real_rename == NULL)
  889             init_all();
  890 
  891         size_t len1 = strlen(oldpath);
  892         size_t len2 = strlen(newpath);
  893         bool need_to_reprotect1 = unprotectBuf(oldpath, len1);
  894         bool need_to_reprotect2 = unprotectBuf(newpath, len2);
  895 
  896         int rv = (*_real_rename)(oldpath, newpath);
  897 
  898         if (need_to_reprotect1)
  899             reprotectBuf(oldpath, len1);
  900         if (need_to_reprotect2)
  901             reprotectBuf(newpath, len2);
  902 
  903         return rv;
  904     }
  905 
  906     int chmod(const char * path, mode_t mode) {
  907         if (_real_chmod == NULL)
  908             init_all();
  909 
  910         size_t len = strlen(path);
  911         bool need_to_reprotect = unprotectBuf(path, len);
  912 
  913         int rv = (*_real_chmod)(path, mode);
  914 
  915         if (need_to_reprotect)
  916             reprotectBuf(path, len);
  917 
  918         return rv;
  919     }
  920 
  921     int readlink(const char * path, char * buf, size_t bufsiz) {
  922         if (_real_readlink == NULL)
  923             init_all();
  924 
  925         size_t len = strlen(path);
  926         bool need_to_reprotect1 = unprotectBuf(path, len);
  927         bool need_to_reprotect2 = unprotectBuf(buf, bufsiz);
  928 
  929         int rv = (*_real_readlink)(path, buf, bufsiz);
  930 
  931         if (need_to_reprotect1)
  932             reprotectBuf(path, len);
  933         if (need_to_reprotect2)
  934             reprotectBuf(buf, bufsiz);
  935 
  936         return rv;
  937     }
  938 
  939     int creat(const char * pathname, mode_t mode) {
  940         if (_real_creat == NULL)
  941             init_all();
  942 
  943         size_t len = strlen(pathname) + 1;
  944         bool need_to_reprotect = unprotectBuf(pathname, len);
  945 
  946         int rv = (*_real_creat)(pathname, mode);
  947         dbprintf("creat(%s, %x) returned %d\n", pathname, mode, rv);
  948 
  949         if (need_to_reprotect)
  950             reprotectBuf(pathname, len);
  951 
  952         return rv;
  953     }
  954 
  955     int open(const char * pathname, int flags, mode_t mode) {
  956         if (_real_open == NULL)
  957             init_all();
  958 
  959         size_t len = strlen(pathname) + 1;
  960         bool need_to_reprotect = unprotectBuf(pathname, len);
  961 
  962         int rv = (*_real_open)(pathname, flags, mode);
  963         dbprintf("open(\"%s\", %x, %x) returned %d\n", pathname, flags, mode, rv);
  964 
  965         if (need_to_reprotect)
  966             reprotectBuf(pathname, len);
  967 
  968         return rv;
  969     }
  970 
  971     int open64(const char * pathname, int flags, mode_t mode) {
  972         if (_real_open64 == NULL)
  973             init_all();
  974 
  975         size_t len = strlen(pathname) + 1;
  976         bool need_to_reprotect = unprotectBuf(pathname, len);
  977 
  978         int rv = (*_real_open64)(pathname, flags, mode);
  979         dbprintf("open64(\"%s\", %x, %x) returned %d\n", pathname, flags, mode, rv);
  980 #if 0
  981         if (need_to_reprotect)
  982             reprotectBuf(pathname, len);
  983 #endif
  984         return rv;
  985     }
  986 
  987     FILE * fopen(const char * path, const char * mode) {
  988         if (_real_fopen == NULL)
  989             init_all();
  990 
  991         size_t len1 = strlen(path) + 1;
  992         size_t len2 = strlen(mode) + 1;
  993         bool need_to_reprotect1 = unprotectBuf(path, len1);
  994         bool need_to_reprotect2 = unprotectBuf(mode, len2);
  995 
  996         FILE * rv = (*_real_fopen)(path, mode);
  997         dbprintf("fopen(\"%s\", \"%s\") returned %d\n", path, mode, rv);
  998 
  999         if (need_to_reprotect1)
 1000             reprotectBuf(path, len1);
 1001         if (need_to_reprotect2)
 1002             reprotectBuf(mode, len2);
 1003 
 1004         return rv;
 1005     }
 1006 
 1007     FILE * fopen64(const char * path, const char * mode) {
 1008         if (_real_fopen64 == NULL)
 1009             init_all();
 1010 
 1011         size_t len1 = strlen(path) + 1;
 1012         size_t len2 = strlen(mode) + 1;
 1013         bool need_to_reprotect1 = unprotectBuf(path, len1);
 1014         bool need_to_reprotect2 = unprotectBuf(mode, len2);
 1015 
 1016         FILE * rv = (*_real_fopen64)(path, mode);
 1017         dbprintf("fopen64(\"%s\", \"%s\") returned %d\n", path, mode, rv);
 1018 
 1019         if (need_to_reprotect1)
 1020             reprotectBuf(path, len1);
 1021         if (need_to_reprotect2)
 1022             reprotectBuf(mode, len2);
 1023 
 1024         return rv;
 1025     }
 1026 
 1027     int access(const char * pathname, int mode) {
 1028         if (_real_access == NULL)
 1029             init_all();
 1030 
 1031         size_t len = strlen(pathname);
 1032         bool need_to_reprotect = unprotectBuf(pathname, len);
 1033 
 1034         int rv = (*_real_access)(pathname, mode);
 1035 #if 0
 1036         if (need_to_reprotect)
 1037             reprotectBuf(pathname, len);
 1038 #endif
 1039         dbprintf("access(%p, %x) = %d\n", pathname, mode, rv);
 1040         return rv;
 1041     }
 1042 
 1043     int chown(const char * path, uid_t owner, gid_t group) {
 1044         if (_real_chown == NULL)
 1045             init_all();
 1046 
 1047         size_t len = strlen(path);
 1048         bool need_to_reprotect = unprotectBuf(path, len);
 1049 
 1050         int rv = (*_real_chown)(path, owner, group);
 1051 
 1052         if (need_to_reprotect)
 1053             reprotectBuf(path, len);
 1054 
 1055         return rv;
 1056     }
 1057 
 1058     int lchown(const char * path, uid_t owner, gid_t group) {
 1059         if (_real_lchown == NULL)
 1060             init_all();
 1061 
 1062         size_t len = strlen(path);
 1063         bool need_to_reprotect = unprotectBuf(path, len);
 1064 
 1065         int rv = (*_real_lchown)(path, owner, group);
 1066 
 1067         if (need_to_reprotect)
 1068             reprotectBuf(path, len);
 1069 
 1070         return rv;
 1071     }
 1072 
 1073     int utime(const char * filename, const struct utimbuf * buf) {
 1074         if (_real_utime == NULL)
 1075             init_all();
 1076 
 1077         size_t len = strlen(filename);
 1078         bool need_to_reprotect1 = unprotectBuf(filename, len);
 1079         bool need_to_reprotect2 = unprotectBuf(buf, sizeof(*buf));
 1080 
 1081         int rv = (*_real_utime)(filename, buf);
 1082 
 1083         if (need_to_reprotect1)
 1084             reprotectBuf(filename, len);
 1085         if (need_to_reprotect2)
 1086             reprotectBuf(buf, sizeof(*buf));
 1087 
 1088         return rv;
 1089     }
 1090 
 1091     int utimes(const char * filename, const struct timeval * tvp) {
 1092         if (_real_utimes == NULL)
 1093             init_all();
 1094 
 1095         size_t len = strlen(filename);
 1096         bool need_to_reprotect1 = unprotectBuf(filename, len);
 1097         bool need_to_reprotect2 = unprotectBuf(tvp, sizeof(*tvp));
 1098 
 1099         int rv = (*_real_utimes)(filename, tvp);
 1100 
 1101         if (need_to_reprotect1)
 1102             reprotectBuf(filename, len);
 1103         if (need_to_reprotect2)
 1104             reprotectBuf(tvp, sizeof(*tvp));
 1105 
 1106         return rv;
 1107     }
 1108 
 1109     int llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t * result, unsigned int whence) {
 1110         if (_real_llseek == NULL)
 1111             init_all();
 1112 
 1113         bool need_to_reprotect = unprotectBuf(result, sizeof(*result));
 1114 
 1115         int rv = (*_real_llseek)(fd, offset_high, offset_low, result, whence);
 1116 
 1117         if (need_to_reprotect)
 1118             reprotectBuf(result, sizeof(*result));
 1119 
 1120         return rv;
 1121     }
 1122 
 1123     ssize_t read(int fd, void * buf, size_t count) {
 1124         if (_real_read == NULL)
 1125             init_all();
 1126 
 1127         bool need_to_reprotect = unprotectBuf(buf, count);
 1128 
 1129         ssize_t rv = (*_real_read)(fd, buf, count);
 1130         dbprintf("read(%d, %p, %u) returned %d\n", fd, buf, count, rv);
 1131 
 1132         if (need_to_reprotect)
 1133             reprotectBuf(buf, count);
 1134 
 1135         return rv;
 1136     }
 1137 
 1138     size_t fread(void * ptr, size_t size, size_t nmemb, FILE * stream) {
 1139         if (_real_fread == NULL)
 1140             init_all();
 1141 
 1142         bool need_to_reprotect = unprotectBuf(ptr, size * nmemb);
 1143 
 1144         size_t rv = (*_real_fread)(ptr, size, nmemb, stream);
 1145         dbprintf("fread(%p, %u, %u, %p) returned %u\n", ptr, size, nmemb, stream, rv);
 1146 
 1147         if (need_to_reprotect)
 1148             reprotectBuf(ptr, size * nmemb);
 1149 
 1150         return rv;
 1151     }
 1152 
 1153     ssize_t readv(int fd, const struct iovec * vector, int count) {
 1154         if (_real_readv == NULL)
 1155             init_all();
 1156 
 1157         bool need_to_reprotect[count];
 1158         for (int i = 0; i < count; i++)
 1159             need_to_reprotect[i] = unprotectBuf(vector[i].iov_base, vector[i].iov_len);
 1160 
 1161         ssize_t rv = (*_real_readv)(fd, vector, count);
 1162         dbprintf("readv(%d, %p, %d) returned %d\n", fd, vector, count, rv);
 1163 
 1164         for (int i = 0; i < count; i++)
 1165             if (need_to_reprotect[i])
 1166                 reprotectBuf(vector[i].iov_base, vector[i].iov_len);
 1167 
 1168         return rv;
 1169     }
 1170 
 1171     ssize_t write(int fd, const void * buf, size_t count) {
 1172         if (_real_write == NULL)
 1173             init_all();
 1174 
 1175         bool need_to_reprotect = unprotectBuf(buf, count);
 1176 
 1177         ssize_t rv = (*_real_write)(fd, buf, count);
 1178         dbprintf("write(%d, %p, %d) returned %d\n", fd, buf, count, rv);
 1179 
 1180         if (need_to_reprotect)
 1181             reprotectBuf(buf, count);
 1182 
 1183         return rv;
 1184     }
 1185 
 1186     size_t fwrite(const void * ptr, size_t size, size_t nmemb, FILE * stream) {
 1187         if (_real_fwrite == NULL)
 1188             init_all();
 1189 
 1190         bool need_to_reprotect = unprotectBuf(ptr, size * nmemb);
 1191 
 1192         size_t rv = (*_real_fwrite)(ptr, size, nmemb, stream);
 1193         dbprintf("fwrite(%p, %u, %u, %p) returned %u\n", ptr, size, nmemb, stream, rv);
 1194 
 1195         if (need_to_reprotect)
 1196             reprotectBuf(ptr, size * nmemb);
 1197 
 1198         return rv;
 1199     }
 1200 
 1201     ssize_t writev(int fd, const struct iovec * vector, int count) {
 1202         if (_real_writev == NULL)
 1203             init_all();
 1204 
 1205         bool need_to_reprotect[count];
 1206         for (int i = 0; i < count; i++)
 1207             need_to_reprotect[i] = unprotectBuf(vector[i].iov_base, vector[i].iov_len);
 1208 
 1209         ssize_t rv = (*_real_writev)(fd, vector, count);
 1210         dbprintf("writev(%d, %p, %d) returned %d\n", fd, vector, count, rv);
 1211 
 1212         for (int i = 0; i < count; i++)
 1213             if (need_to_reprotect[i])
 1214                 reprotectBuf(vector[i].iov_base, vector[i].iov_len);
 1215 
 1216         return rv;
 1217     }
 1218 
 1219     ssize_t pread(int fd, void * buf, size_t count, off_t offset) {
 1220         if (_real_pread == NULL)
 1221             init_all();
 1222 
 1223         bool need_to_reprotect = unprotectBuf(buf, count);
 1224 
 1225         ssize_t rv = (*_real_pread)(fd, buf, count, offset);
 1226 
 1227         if (need_to_reprotect)
 1228             reprotectBuf(buf, count);
 1229 
 1230         return rv;
 1231     }
 1232 
 1233     ssize_t pwrite(int fd, const void * buf, size_t count, off_t offset) {
 1234         if (_real_pwrite == NULL)
 1235             init_all();
 1236 
 1237         bool need_to_reprotect = unprotectBuf(buf, count);
 1238 
 1239         ssize_t rv = (*_real_pwrite)(fd, buf, count, offset);
 1240 
 1241         if (need_to_reprotect)
 1242             reprotectBuf(buf, count);
 1243 
 1244         return rv;
 1245     }
 1246 
 1247     int mkdir(const char * pathname, mode_t mode) {
 1248         if (_real_mkdir == NULL)
 1249             init_all();
 1250 
 1251         size_t len = strlen(pathname);
 1252         bool need_to_reprotect = unprotectBuf(pathname, len);
 1253 
 1254         int rv = (*_real_mkdir)(pathname, mode);
 1255 #if 0
 1256         if (need_to_reprotect)
 1257             reprotectBuf(pathname, len);
 1258 #endif
 1259         return rv;
 1260     }
 1261 
 1262     int chdir(const char * path) {
 1263         if (_real_chdir == NULL)
 1264             init_all();
 1265 
 1266         size_t len = strlen(path);
 1267         bool need_to_reprotect = unprotectBuf(path, len);
 1268 
 1269         int rv = (*_real_chdir)(path);
 1270 
 1271         if (need_to_reprotect)
 1272             reprotectBuf(path, len);
 1273 
 1274         return rv;
 1275     }
 1276 
 1277     int rmdir(const char * pathname) {
 1278         if (_real_rmdir == NULL)
 1279             init_all();
 1280 
 1281         size_t len = strlen(pathname);
 1282         bool need_to_reprotect = unprotectBuf(pathname, len);
 1283 
 1284         int rv = (*_real_rmdir)(pathname);
 1285 
 1286         if (need_to_reprotect)
 1287             reprotectBuf(pathname, len);
 1288 
 1289         return rv;
 1290     }
 1291 
 1292     int setsockopt(int s, int level, int optname, const void * optval, socklen_t optlen) {
 1293         if (_real_setsockopt == NULL)
 1294             init_all();
 1295 
 1296         bool need_to_reprotect = unprotectBuf(optval, optlen);
 1297 
 1298         int rv = (*_real_setsockopt)(s, level, optname, optval, optlen);
 1299 
 1300         if (need_to_reprotect)
 1301             reprotectBuf(optval, optlen);
 1302 
 1303         return rv;
 1304     }
 1305 
 1306     int getsockopt(int s, int level, int optname, void * optval, socklen_t * optlen) {
 1307         if (_real_getsockopt == NULL)
 1308             init_all();
 1309 
 1310         size_t len = *optlen;
 1311         bool need_to_reprotect = unprotectBuf(optval, len);
 1312 
 1313         int rv = (*_real_getsockopt)(s, level, optname, optval, optlen);
 1314 
 1315         if (need_to_reprotect)
 1316             reprotectBuf(optval, len);
 1317 
 1318         return rv;
 1319     }
 1320 
 1321     int bind(int sockfd, const struct sockaddr * my_addr, socklen_t addrlen) {
 1322         if (_real_bind == NULL)
 1323             init_all();
 1324 
 1325         bool need_to_reprotect = unprotectBuf(my_addr, addrlen);
 1326 
 1327         int rv = (*_real_bind)(sockfd, my_addr, addrlen);
 1328 
 1329         if (need_to_reprotect)
 1330             reprotectBuf(my_addr, addrlen);
 1331 
 1332         return rv;
 1333     }
 1334 
 1335     int connect(int sockfd, const struct sockaddr * serv_addr, socklen_t addrlen) {
 1336         if (_real_connect == NULL)
 1337             init_all();
 1338 
 1339         bool need_to_reprotect = unprotectBuf(serv_addr, addrlen);
 1340 
 1341         int rv = (*_real_connect)(sockfd, serv_addr, addrlen);
 1342 
 1343         if (need_to_reprotect)
 1344             reprotectBuf(serv_addr, addrlen);
 1345 
 1346         return rv;
 1347     }
 1348 
 1349     int accept(int s, struct sockaddr * addr, socklen_t * addrlen) {
 1350         if (_real_accept == NULL)
 1351             init_all();
 1352 
 1353         size_t len = *addrlen;
 1354         bool need_to_reprotect = unprotectBuf(addr, len);
 1355 
 1356         int rv = (*_real_accept)(s, addr, addrlen);
 1357 
 1358         if (need_to_reprotect)
 1359             reprotectBuf(addr, len);
 1360 
 1361         return rv;
 1362     }
 1363 
 1364     int getsockname(int s, struct sockaddr * name, socklen_t * namelen) {
 1365         if (_real_getsockname == NULL)
 1366             init_all();
 1367 
 1368         size_t len = *namelen;
 1369         bool need_to_reprotect = unprotectBuf(name, len);
 1370 
 1371         int rv = (*_real_getsockname)(s, name, namelen);
 1372 
 1373         if (need_to_reprotect)
 1374             reprotectBuf(name, len);
 1375 
 1376         return rv;
 1377     }
 1378 
 1379     int getpeername(int s, struct sockaddr * name, socklen_t * namelen) {
 1380         if (_real_getpeername == NULL)
 1381             init_all();
 1382 
 1383         size_t len = *namelen;
 1384         bool need_to_reprotect = unprotectBuf(name, len);
 1385 
 1386         int rv = (*_real_getpeername)(s, name, namelen);
 1387 
 1388         if (need_to_reprotect)
 1389             reprotectBuf(name, len);
 1390 
 1391         return rv;
 1392     }
 1393 
 1394     ssize_t send(int s, const void * buf, size_t len, int flags) {
 1395         if (_real_send == NULL)
 1396             init_all();
 1397 
 1398         bool need_to_reprotect = unprotectBuf(buf, len);
 1399 
 1400         ssize_t rv = (*_real_send)(s, buf, len, flags);
 1401 
 1402         if (need_to_reprotect)
 1403             reprotectBuf(buf, len);
 1404 
 1405         return rv;
 1406     }
 1407 
 1408     ssize_t sendto(int s, const void * buf, size_t len, int flags, const struct sockaddr * to, socklen_t tolen) {
 1409         if (_real_sendto == NULL)
 1410             init_all();
 1411 
 1412         bool need_to_reprotect1 = unprotectBuf(buf, len);
 1413         bool need_to_reprotect2 = unprotectBuf(to, tolen);
 1414 
 1415         ssize_t rv = (*_real_sendto)(s, buf, len, flags, to, tolen);
 1416 
 1417         if (need_to_reprotect1)
 1418             reprotectBuf(buf, len);
 1419         if (need_to_reprotect2)
 1420             reprotectBuf(to, tolen);
 1421 
 1422         return rv;
 1423     }
 1424 
 1425     ssize_t sendmsg(int s, const struct msghdr * msg, int flags) {
 1426         if (_real_sendmsg == NULL)
 1427             init_all();
 1428 
 1429         void * addr = msg->msg_name;
 1430         size_t len = msg->msg_namelen;
 1431         bool need_to_reprotect = unprotectBuf(addr, len);
 1432 
 1433         ssize_t rv = (*_real_sendmsg)(s, msg, flags);
 1434 
 1435         if (need_to_reprotect)
 1436             reprotectBuf(addr, len);
 1437 
 1438         return rv;
 1439     }
 1440 
 1441     ssize_t recv(int s, void * buf, size_t len, int flags) {
 1442         if (_real_recv == NULL)
 1443             init_all();
 1444 
 1445         bool need_to_reprotect = unprotectBuf(buf, len);
 1446 
 1447         ssize_t rv = (*_real_recv)(s, buf, len, flags);
 1448 
 1449         if (need_to_reprotect)
 1450             reprotectBuf(buf, len);
 1451 
 1452         return rv;
 1453     }
 1454 
 1455     ssize_t recvfrom(int s, void * buf, size_t len, int flags, struct sockaddr * from, socklen_t * fromlen) {
 1456         if (_real_recvfrom == NULL)
 1457             init_all();
 1458 
 1459         size_t len2 = *fromlen;
 1460         bool need_to_reprotect1 = unprotectBuf(buf, len);
 1461         bool need_to_reprotect2 = unprotectBuf(from, len2);
 1462 
 1463         ssize_t rv = (*_real_recvfrom)(s, buf, len, flags, from, fromlen);
 1464 
 1465         if (need_to_reprotect1)
 1466             reprotectBuf(buf, len);
 1467         if (need_to_reprotect2)
 1468             reprotectBuf(from, len2);
 1469 
 1470         return rv;
 1471     }
 1472 
 1473     ssize_t recvmsg(int s, struct msghdr * msg, int flags) {
 1474         if (_real_recvmsg == NULL)
 1475             init_all();
 1476 
 1477         void * addr = msg->msg_name;
 1478         size_t len = msg->msg_namelen;
 1479         bool need_to_reprotect = unprotectBuf(addr, len);
 1480 
 1481         ssize_t rv = (*_real_recvmsg)(s, msg, flags);
 1482 
 1483         if (need_to_reprotect)
 1484             reprotectBuf(addr, len);
 1485 
 1486         return rv;
 1487     }
 1488 
 1489     int poll(struct pollfd * ufds, nfds_t nfds, int timeout) {
 1490         if (_real_poll == NULL)
 1491             init_all();
 1492 
 1493         bool need_to_reprotect = unprotectBuf(ufds, nfds * sizeof(*ufds));
 1494         dbprintf("poll(%p, %d, %d)\n", ufds, nfds, timeout);
 1495 
 1496         int rv = (*_real_poll)(ufds, nfds, timeout);
 1497         dbprintf("poll(%p, %d, %d) returned %d\n", ufds, nfds, timeout, rv);
 1498 
 1499         if (need_to_reprotect)
 1500             reprotectBuf(ufds, nfds * sizeof(*ufds));
 1501 
 1502         return rv;
 1503     }
 1504 
 1505     int select(int n, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval * timeout) {
 1506         if (_real_select == NULL)
 1507             init_all();
 1508 
 1509         size_t len = n / 8;
 1510         bool need_to_reprotect1 = unprotectBuf(readfds, len);
 1511         bool need_to_reprotect2 = unprotectBuf(writefds, len);
 1512         bool need_to_reprotect3 = unprotectBuf(exceptfds, len);
 1513         bool need_to_reprotect4 = unprotectBuf(timeout, sizeof(*timeout));
 1514 
 1515         int rv = (*_real_select)(n, readfds, writefds, exceptfds, timeout);
 1516 
 1517         if (need_to_reprotect1)
 1518             reprotectBuf(readfds, len);
 1519         if (need_to_reprotect2)
 1520             reprotectBuf(writefds, len);
 1521         if (need_to_reprotect3)
 1522             reprotectBuf(exceptfds, len);
 1523         if (need_to_reprotect4)
 1524             reprotectBuf(timeout, sizeof(*timeout));
 1525 
 1526         return rv;
 1527     }
 1528 
 1529     int pselect(int n, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, const struct timespec * timeout, const sigset_t * sigmask) {
 1530         if (_real_pselect == NULL)
 1531             init_all();
 1532 
 1533         size_t len = n / 8;
 1534         bool need_to_reprotect1 = unprotectBuf(readfds, len);
 1535         bool need_to_reprotect2 = unprotectBuf(writefds, len);
 1536         bool need_to_reprotect3 = unprotectBuf(exceptfds, len);
 1537         bool need_to_reprotect4 = unprotectBuf(timeout, sizeof(*timeout));
 1538         bool need_to_reprotect5 = unprotectBuf(sigmask, sizeof(*sigmask));
 1539 
 1540         int rv = (*_real_pselect)(n, readfds, writefds, exceptfds, timeout, sigmask);
 1541 
 1542         if (need_to_reprotect1)
 1543             reprotectBuf(readfds, len);
 1544         if (need_to_reprotect2)
 1545             reprotectBuf(writefds, len);
 1546         if (need_to_reprotect3)
 1547             reprotectBuf(exceptfds, len);
 1548         if (need_to_reprotect4)
 1549             reprotectBuf(timeout, sizeof(*timeout));
 1550         if (need_to_reprotect5)
 1551             reprotectBuf(sigmask, sizeof(*sigmask));
 1552 
 1553         return rv;
 1554     }
 1555 
 1556     int uname(struct utsname * buf) {
 1557         if (_real_uname == NULL)
 1558             init_all();
 1559 
 1560         bool need_to_reprotect = unprotectBuf(buf, sizeof(*buf));
 1561 
 1562         int rv = (*_real_uname)(buf);
 1563 
 1564         if (need_to_reprotect)
 1565             reprotectBuf(buf, sizeof(*buf));
 1566 
 1567         return rv;
 1568     }
 1569 #if 0
 1570     int getrlimit(int resource, struct rlimit * rlim) {
 1571         if (_real_getrlimit == NULL)
 1572             init_all();
 1573 
 1574         bool need_to_reprotect = unprotectBuf(rlim, sizeof(*rlim));
 1575 
 1576         int rv = (*_real_getrlimit)(resource, rlim);
 1577         dbprintf("getrlimit(%d, %p) returned %d\n", resource, rlim, rv);
 1578 
 1579         if (need_to_reprotect)
 1580             reprotectBuf(rlim, sizeof(*rlim));
 1581 
 1582         return rv;
 1583     }
 1584 #endif
 1585     int setrlimit(int resource, const struct rlimit * rlim) {
 1586         if (_real_setrlimit == NULL)
 1587             init_all();
 1588 
 1589         bool need_to_reprotect = unprotectBuf(rlim, sizeof(*rlim));
 1590 
 1591         int rv = (*_real_setrlimit)(resource, rlim);
 1592 
 1593         if (need_to_reprotect)
 1594             reprotectBuf(rlim, sizeof(*rlim));
 1595 
 1596         return rv;
 1597     }
 1598 
 1599     int getrusage(int who, struct rusage * usage) {
 1600         if (_real_getrusage == NULL)
 1601             init_all();
 1602 
 1603         bool need_to_reprotect = unprotectBuf(usage, sizeof(*usage));
 1604 
 1605         int rv = (*_real_getrusage)(who, usage);
 1606 
 1607         if (need_to_reprotect)
 1608             reprotectBuf(usage, sizeof(*usage));
 1609 
 1610         return rv;
 1611     }
 1612 
 1613     int shmctl(int shmid, int cmd, struct shmid_ds * buf) {
 1614         if (_real_shmctl == NULL)
 1615             init_all();
 1616 
 1617         bool need_to_reprotect = unprotectBuf(buf, sizeof(*buf));
 1618 
 1619         int rv = (*_real_shmctl)(shmid, cmd, buf);
 1620 
 1621         if (need_to_reprotect)
 1622             reprotectBuf(buf, sizeof(*buf));
 1623 
 1624         return rv;
 1625     }
 1626 
 1627     int sysctl(struct __sysctl_args * args) {
 1628         if (_real_sysctl == NULL)
 1629             init_all();
 1630 
 1631         bool need_to_reprotect = unprotectBuf(args, sizeof(*args));
 1632 
 1633         int rv = (*_real_sysctl)(args);
 1634 
 1635         if (need_to_reprotect)
 1636             reprotectBuf(args, sizeof(*args));
 1637 
 1638         return rv;
 1639     }
 1640 
 1641     inline static MemTracer * getMemTracer() {
 1642         static char buf[sizeof(MemTracer)];
 1643         static MemTracer * mt = new (buf) MemTracer;
 1644         return mt;
 1645     }
 1646 
 1647 private:
 1648 
 1649     enum {
 1650         PAGE_SBRK_ANON      = 0x0001,
 1651         PAGE_MMAP_ANON      = 0x0002,
 1652         PAGE_MMAP_PRIVATE   = 0x0004,
 1653         PAGE_MMAP_SHARED    = 0x0008,
 1654         PAGE_MAPPING_MASK   = 0x000F,
 1655 
 1656         PAGE_ON_DEMAND      = 0x0010,
 1657         PAGE_DISCARDED      = 0x0020,
 1658         PAGE_IN_MEMORY      = 0x0040,
 1659         PAGE_STATUS_MASK    = 0x00F0,
 1660 
 1661         PAGE_ORIG_READABLE  = 0x0100,
 1662         PAGE_ORIG_WRITABLE  = 0x0200,
 1663         PAGE_ORIG_PROT_MASK = 0x0F00,
 1664 
 1665         PAGE_CURR_READABLE  = 0x1000,
 1666         PAGE_CURR_WRITABLE  = 0x2000,
 1667         PAGE_CURR_PROT_MASK = 0xF000,
 1668     };
 1669 
 1670     typedef void * callocType (size_t, size_t);
 1671     typedef void * mallocType (size_t);
 1672     typedef void freeType (void * ptr);
 1673     typedef void * reallocType (void *, size_t);
 1674 
 1675     typedef int brkType (void *);
 1676     typedef void * sbrkType (intptr_t);
 1677     typedef void * mmapType (void *, size_t, int, int, int, off_t);
 1678     typedef int munmapType (void *, size_t);
 1679     typedef int madviseType (void *, size_t, int);
 1680     typedef int mprotectType (const void *, size_t, int);
 1681     typedef sighandler_t signalType (int signum, sighandler_t handler);
 1682     typedef int sigactionType (int, const struct sigaction *, struct sigaction *);
 1683 //  typedef void exitType (int);
 1684 
 1685     typedef time_t timeType (time_t *);
 1686     typedef int stimeType (const time_t *);
 1687     typedef int gettimeofdayType (struct timeval *, struct timezone *);
 1688     typedef int settimeofdayType (const struct timeval *, const struct timezone *);
 1689     typedef int getresuidType (uid_t *, uid_t *, uid_t *);
 1690     typedef int getresgidType (gid_t *, gid_t *, gid_t *);
 1691     typedef int sigpendingType (sigset_t *);
 1692     typedef int sigprocmaskType (int, const sigset_t *, sigset_t *);
 1693     typedef int sched_setschedulerType (pid_t, int, const struct sched_param *);
 1694     typedef int sched_setparamType (pid_t, const struct sched_param *);
 1695     typedef int sched_getparamType (pid_t, struct sched_param *);
 1696     typedef pid_t waitType (int *);
 1697     typedef pid_t wait3Type (int *, int, struct rusage *);
 1698     typedef pid_t wait4Type (pid_t, int *, int, struct rusage *);
 1699     typedef int waitidType (idtype_t, id_t, siginfo_t *, int);
 1700     typedef pid_t waitpidType (pid_t, int *, int);
 1701     typedef int statfsType (const char *, struct statfs *);
 1702     typedef int statfs64Type (const char *, struct statfs64 *);
 1703     typedef int fstatfsType (int, struct statfs *);
 1704     typedef int fstatfs64Type (int, struct statfs64 *);
 1705     typedef int linkType (const char *, const char *);
 1706     typedef int symlinkType (const char *, const char *);
 1707     typedef int unlinkType (const char *);
 1708     typedef int renameType (const char *, const char *);
 1709     typedef int chmodType (const char *, mode_t);
 1710     typedef int readlinkType (const char *, char *, size_t);
 1711     typedef int creatType (const char *, mode_t);
 1712     typedef int openType (const char *, int, mode_t);
 1713     typedef int open64Type (const char *, int, mode_t);
 1714     typedef FILE * fopenType (const char *, const char *);
 1715     typedef FILE * fopen64Type (const char *, const char *);
 1716     typedef int accessType (const char *, int);
 1717     typedef int chownType (const char *, uid_t, gid_t);
 1718     typedef int lchownType (const char *, uid_t, gid_t);
 1719     typedef int utimeType (const char *, const struct utimbuf *);
 1720     typedef int utimesType (const char *, const struct timeval *);
 1721     typedef int llseekType (unsigned int, unsigned long, unsigned long, loff_t *, unsigned int);
 1722     typedef ssize_t readType (int, void *, size_t);
 1723     typedef size_t freadType (void *, size_t, size_t, FILE *);
 1724     typedef ssize_t readvType (int, const struct iovec *, int);
 1725     typedef ssize_t writeType (int, const void *, size_t);
 1726     typedef size_t fwriteType (const void *, size_t, size_t, FILE *);
 1727     typedef ssize_t writevType (int, const struct iovec *, int);
 1728     typedef ssize_t preadType (int, void *, size_t, off_t);
 1729     typedef ssize_t pwriteType (int, const void *, size_t, off_t);
 1730     typedef int mkdirType (const char *, mode_t);
 1731     typedef int chdirType (const char *);
 1732     typedef int rmdirType (const char *);
 1733     typedef int setsockoptType (int, int, int, const void *, socklen_t);
 1734     typedef int getsockoptType (int, int, int, void *, socklen_t *);
 1735     typedef int bindType (int, const struct sockaddr *, socklen_t);
 1736     typedef int connectType (int, const struct sockaddr *, socklen_t);
 1737     typedef int acceptType (int, struct sockaddr *, socklen_t *);
 1738     typedef int getsocknameType (int, struct sockaddr *, socklen_t *);
 1739     typedef int getpeernameType (int, struct sockaddr *, socklen_t *);
 1740     typedef ssize_t sendType (int, const void *, size_t, int);
 1741     typedef ssize_t sendtoType (int, const void *, size_t, int, const struct sockaddr *, socklen_t);
 1742     typedef ssize_t sendmsgType (int, const struct msghdr *, int);
 1743     typedef ssize_t recvType (int, void *, size_t, int);
 1744     typedef ssize_t recvfromType (int, void *, size_t, int, struct sockaddr *, socklen_t *);
 1745     typedef ssize_t recvmsgType (int, struct msghdr *, int);
 1746     typedef int pollType (struct pollfd *, nfds_t, int);
 1747     typedef int selectType (int, fd_set *, fd_set *, fd_set *, struct timeval *);
 1748     typedef int pselectType (int, fd_set *, fd_set *, fd_set *, const struct timespec *, const sigset_t *);
 1749     typedef int unameType (struct utsname *);
 1750     typedef int getrlimitType (int, struct rlimit *);
 1751     typedef int setrlimitType (int, const struct rlimit *);
 1752     typedef int getrusageType (int, struct rusage *);
 1753     typedef int shmctlType (int, int, struct shmid_ds *);
 1754     typedef int sysctlType (struct __sysctl_args *);
 1755 
 1756     typedef void saHandlerType (int);
 1757     typedef void saSigactionType (int, siginfo_t *, void *);
 1758 
 1759     typedef HL::Guard<PosixRecursiveLockType> MemTracerLock;
 1760 
 1761     PosixRecursiveLockType _lock;
 1762 
 1763     bool _in_dlsym;
 1764 
 1765     callocType * _real_calloc;
 1766     mallocType * _real_malloc;
 1767     freeType * _real_free;
 1768     reallocType * _real_realloc;
 1769 
 1770     brkType * _real_brk;
 1771     sbrkType * _real_sbrk;
 1772     mmapType * _real_mmap;
 1773     munmapType * _real_munmap;
 1774     madviseType * _real_madvise;
 1775     mprotectType * _real_mprotect;
 1776     signalType * _real_signal;
 1777     sigactionType * _real_sigaction;
 1778 //  exitType * _real_exit;
 1779 
 1780     timeType * _real_time;
 1781     stimeType * _real_stime;
 1782     gettimeofdayType * _real_gettimeofday;
 1783     settimeofdayType * _real_settimeofday;
 1784     getresuidType * _real_getresuid;
 1785     getresgidType * _real_getresgid;
 1786     sigpendingType * _real_sigpending;
 1787     sigprocmaskType * _real_sigprocmask;
 1788     sched_setschedulerType * _real_sched_setscheduler;
 1789     sched_setparamType * _real_sched_setparam;
 1790     sched_getparamType * _real_sched_getparam;
 1791     waitType * _real_wait;
 1792     wait3Type * _real_wait3;
 1793     wait4Type * _real_wait4;
 1794     waitidType * _real_waitid;
 1795     waitpidType * _real_waitpid;
 1796     statfsType * _real_statfs;
 1797     statfs64Type * _real_statfs64;
 1798     fstatfsType * _real_fstatfs;
 1799     fstatfs64Type * _real_fstatfs64;
 1800     linkType * _real_link;
 1801     symlinkType * _real_symlink;
 1802     unlinkType * _real_unlink;
 1803     renameType * _real_rename;
 1804     chmodType * _real_chmod;
 1805     readlinkType * _real_readlink;
 1806     creatType * _real_creat;
 1807     openType * _real_open;
 1808     open64Type * _real_open64;
 1809     fopenType * _real_fopen;
 1810     fopen64Type * _real_fopen64;
 1811     accessType * _real_access;
 1812     chownType * _real_chown;
 1813     lchownType * _real_lchown;
 1814     utimeType * _real_utime;
 1815     utimesType * _real_utimes;
 1816     llseekType * _real_llseek;
 1817     readType * _real_read;
 1818     freadType * _real_fread;
 1819     readvType * _real_readv;
 1820     writeType * _real_write;
 1821     fwriteType * _real_fwrite;
 1822     writevType * _real_writev;
 1823     preadType * _real_pread;
 1824     pwriteType * _real_pwrite;
 1825     mkdirType * _real_mkdir;
 1826     chdirType * _real_chdir;
 1827     rmdirType * _real_rmdir;
 1828     setsockoptType * _real_setsockopt;
 1829     getsockoptType * _real_getsockopt;
 1830     bindType * _real_bind;
 1831     connectType * _real_connect;
 1832     acceptType * _real_accept;
 1833     getsocknameType * _real_getsockname;
 1834     getpeernameType * _real_getpeername;
 1835     sendType * _real_send;
 1836     sendtoType * _real_sendto;
 1837     sendmsgType * _real_sendmsg;
 1838     recvType * _real_recv;
 1839     recvfromType * _real_recvfrom;
 1840     recvmsgType * _real_recvmsg;
 1841     pollType * _real_poll;
 1842     selectType * _real_select;
 1843     pselectType * _real_pselect;
 1844     unameType * _real_uname;
 1845     getrlimitType * _real_getrlimit;
 1846     setrlimitType * _real_setrlimit;
 1847     getrusageType * _real_getrusage;
 1848     shmctlType * _real_shmctl;
 1849     sysctlType * _real_sysctl;
 1850 
 1851     // stored SIGSEGV handler from the application
 1852     saHandlerType * _stored_segv_handler;
 1853     saSigactionType * _stored_segv_sigaction;
 1854 
 1855     ssize_t currentAllocatedMmap;
 1856     ssize_t currentAllocatedSbrk;
 1857     ssize_t currentMmapDiscarded;
 1858     ssize_t currentSbrkDiscarded;
 1859     ssize_t currentMmapUntouched;
 1860     ssize_t currentSbrkUntouched;
 1861     ssize_t maxAllocated;
 1862     char * initialBreak;
 1863     char * currentBreak;
 1864 
 1865     static __thread int trace_fd;
 1866 
 1867 #ifdef DEBUG
 1868     static __thread int debug_fd;
 1869 #endif
 1870 
 1871     PageStatusMap _page_status_map;
 1872 
 1873     void * unprotectedWindow[UNPROTECTED_SIZE]; // a FIFO window of currently unprotected pages
 1874     int windowPointer;
 1875 
 1876     MemTracer()
 1877         : _lock(),
 1878           _in_dlsym(false),
 1879           _real_calloc(NULL),
 1880           _real_malloc(NULL),
 1881           _real_free(NULL),
 1882           _real_realloc(NULL),
 1883           _real_brk(NULL),
 1884           _real_sbrk(NULL),
 1885           _real_mmap(NULL),
 1886           _real_munmap(NULL),
 1887           _real_madvise(NULL),
 1888           _real_mprotect(NULL),
 1889           _real_sigaction(NULL),
 1890 //        _real_exit(NULL),
 1891           _stored_segv_handler(NULL),
 1892           _stored_segv_sigaction(NULL),
 1893           currentAllocatedMmap(0),
 1894           currentAllocatedSbrk(0),
 1895           currentMmapDiscarded(0),
 1896           currentSbrkDiscarded(0),
 1897           currentMmapUntouched(0),
 1898           currentSbrkUntouched(0),
 1899           maxAllocated(0),
 1900           initialBreak(NULL),
 1901           currentBreak(NULL),
 1902           _page_status_map(),
 1903           windowPointer(0) {
 1904 
 1905         for (int i = 0; i < UNPROTECTED_SIZE; i++) {
 1906             unprotectedWindow[i] = NULL;
 1907         }
 1908 
 1909 //      dbprintf("MemTracer starting...\n");
 1910     }
 1911 
 1912     ~MemTracer() {
 1913         dbprintf("MemTracer terminating...\n");
 1914     }
 1915 
 1916     void init_all() {
 1917         _in_dlsym = true;
 1918 
 1919         _real_calloc = (callocType *) dlsym(RTLD_NEXT, "calloc");
 1920         _real_malloc = (mallocType *) dlsym(RTLD_NEXT, "malloc");
 1921         _real_free = (freeType *) dlsym(RTLD_NEXT, "free");
 1922         _real_realloc = (reallocType *) dlsym(RTLD_NEXT, "realloc");
 1923 
 1924         _real_brk = (brkType *) dlsym(RTLD_NEXT, "brk");
 1925         _real_sbrk = (sbrkType *) dlsym(RTLD_NEXT, "sbrk");
 1926         _real_mmap = (mmapType *) dlsym(RTLD_NEXT, "mmap");
 1927         _real_munmap = (munmapType *) dlsym(RTLD_NEXT, "munmap");
 1928         _real_madvise = (madviseType *) dlsym(RTLD_NEXT, "madvise");
 1929         _real_mprotect = (mprotectType *) dlsym(RTLD_NEXT, "mprotect");
 1930         _real_signal = (signalType *) dlsym(RTLD_NEXT, "signal");
 1931         _real_sigaction = (sigactionType *) dlsym(RTLD_NEXT, "sigaction");
 1932 //      _real_exit = (exitType *) dlsym(RTLD_NEXT, "exit");
 1933 
 1934         _real_time = (timeType *) dlsym(RTLD_NEXT, "time");
 1935         _real_stime = (stimeType *) dlsym(RTLD_NEXT, "stime");
 1936         _real_gettimeofday = (gettimeofdayType *) dlsym(RTLD_NEXT, "gettimeofday");
 1937         _real_settimeofday = (settimeofdayType *) dlsym(RTLD_NEXT, "settimeofday");
 1938         _real_getresuid = (getresuidType *) dlsym(RTLD_NEXT, "getresuid");
 1939         _real_getresgid = (getresgidType *) dlsym(RTLD_NEXT, "getresgid");
 1940         _real_sigpending = (sigpendingType *) dlsym(RTLD_NEXT, "sigpending");
 1941         _real_sigprocmask = (sigprocmaskType *) dlsym(RTLD_NEXT, "sigprocmask");
 1942         _real_sched_setscheduler = (sched_setschedulerType *) dlsym(RTLD_NEXT, "sched_setscheduler");
 1943         _real_sched_setparam = (sched_setparamType *) dlsym(RTLD_NEXT, "sched_setparam");
 1944         _real_sched_getparam = (sched_getparamType *) dlsym(RTLD_NEXT, "sched_getparam");
 1945         _real_wait = (waitType *) dlsym(RTLD_NEXT, "wait");
 1946         _real_wait3 = (wait3Type *) dlsym(RTLD_NEXT, "wait3");
 1947         _real_wait4 = (wait4Type *) dlsym(RTLD_NEXT, "wait4");
 1948         _real_waitid = (waitidType *) dlsym(RTLD_NEXT, "waitid");
 1949         _real_waitpid = (waitpidType *) dlsym(RTLD_NEXT, "waitpid");
 1950         _real_statfs = (statfsType *) dlsym(RTLD_NEXT, "statfs");
 1951         _real_statfs64 = (statfs64Type *) dlsym(RTLD_NEXT, "statfs64");
 1952         _real_fstatfs = (fstatfsType *) dlsym(RTLD_NEXT, "fstatfs");
 1953         _real_fstatfs64 = (fstatfs64Type *) dlsym(RTLD_NEXT, "fstatfs64");
 1954         _real_link = (linkType *) dlsym(RTLD_NEXT, "link");
 1955         _real_symlink = (symlinkType *) dlsym(RTLD_NEXT, "symlink");
 1956         _real_unlink = (unlinkType *) dlsym(RTLD_NEXT, "unlink");
 1957         _real_rename = (renameType *) dlsym(RTLD_NEXT, "rename");
 1958         _real_chmod = (chmodType *) dlsym(RTLD_NEXT, "chmod");
 1959         _real_readlink = (readlinkType *) dlsym(RTLD_NEXT, "readlink");
 1960         _real_creat = (creatType *) dlsym(RTLD_NEXT, "creat");
 1961         _real_open = (openType *) dlsym(RTLD_NEXT, "open");
 1962         _real_open64 = (open64Type *) dlsym(RTLD_NEXT, "open64");
 1963         _real_fopen = (fopenType *) dlsym(RTLD_NEXT, "fopen");
 1964         _real_fopen64 = (fopen64Type *) dlsym(RTLD_NEXT, "fopen64");
 1965         _real_access = (accessType *) dlsym(RTLD_NEXT, "access");
 1966         _real_chown = (chownType *) dlsym(RTLD_NEXT, "chown");
 1967         _real_lchown = (lchownType *) dlsym(RTLD_NEXT, "lchown");
 1968         _real_utime = (utimeType *) dlsym(RTLD_NEXT, "utime");
 1969         _real_utimes = (utimesType *) dlsym(RTLD_NEXT, "utimes");
 1970         _real_llseek = (llseekType *) dlsym(RTLD_NEXT, "llseek");
 1971         _real_read = (readType *) dlsym(RTLD_NEXT, "read");
 1972         _real_fread = (freadType *) dlsym(RTLD_NEXT, "fread");
 1973         _real_readv = (readvType *) dlsym(RTLD_NEXT, "readv");
 1974         _real_write = (writeType *) dlsym(RTLD_NEXT, "write");
 1975         _real_fwrite = (fwriteType *) dlsym(RTLD_NEXT, "fwrite");
 1976         _real_writev = (writevType *) dlsym(RTLD_NEXT, "writev");
 1977         _real_pread = (preadType *) dlsym(RTLD_NEXT, "pread");
 1978         _real_pwrite = (pwriteType *) dlsym(RTLD_NEXT, "pwrite");
 1979         _real_mkdir = (mkdirType *) dlsym(RTLD_NEXT, "mkdir");
 1980         _real_chdir = (chdirType *) dlsym(RTLD_NEXT, "chdir");
 1981         _real_rmdir = (rmdirType *) dlsym(RTLD_NEXT, "rmdir");
 1982         _real_setsockopt = (setsockoptType *) dlsym(RTLD_NEXT, "setsockopt");
 1983         _real_getsockopt = (getsockoptType *) dlsym(RTLD_NEXT, "getsockopt");
 1984         _real_bind = (bindType *) dlsym(RTLD_NEXT, "bind");
 1985         _real_connect = (connectType *) dlsym(RTLD_NEXT, "connect");
 1986         _real_accept = (acceptType *) dlsym(RTLD_NEXT, "accept");
 1987         _real_getsockname = (getsocknameType *) dlsym(RTLD_NEXT, "getsockname");
 1988         _real_getpeername = (getpeernameType *) dlsym(RTLD_NEXT, "getpeername");
 1989         _real_send = (sendType *) dlsym(RTLD_NEXT, "send");
 1990         _real_sendto = (sendtoType *) dlsym(RTLD_NEXT, "sendto");
 1991         _real_sendmsg = (sendmsgType *) dlsym(RTLD_NEXT, "sendmsg");
 1992         _real_recv = (recvType *) dlsym(RTLD_NEXT, "recv");
 1993         _real_recvfrom = (recvfromType *) dlsym(RTLD_NEXT, "recvfrom");
 1994         _real_recvmsg = (recvmsgType *) dlsym(RTLD_NEXT, "recvmsg");
 1995         _real_poll = (pollType *) dlsym(RTLD_NEXT, "poll");
 1996         _real_select = (selectType *) dlsym(RTLD_NEXT, "select");
 1997         _real_pselect = (pselectType *) dlsym(RTLD_NEXT, "pselect");
 1998         _real_uname = (unameType *) dlsym(RTLD_NEXT, "uname");
 1999         _real_getrlimit = (getrlimitType *) dlsym(RTLD_NEXT, "getrlimit");
 2000         _real_setrlimit = (setrlimitType *) dlsym(RTLD_NEXT, "setrlimit");
 2001         _real_getrusage = (getrusageType *) dlsym(RTLD_NEXT, "getrusage");
 2002         _real_shmctl = (shmctlType *) dlsym(RTLD_NEXT, "shmctl");
 2003         _real_sysctl = (sysctlType *) dlsym(RTLD_NEXT, "sysctl");
 2004 
 2005         _in_dlsym = false;
 2006 
 2007         assert(_real_calloc != NULL);
 2008         assert(_real_brk != NULL);
 2009         assert(_real_sbrk != NULL);
 2010         assert(_real_mmap != NULL);
 2011         assert(_real_munmap != NULL);
 2012         assert(_real_madvise != NULL);
 2013         assert(_real_mprotect != NULL);
 2014         assert(_real_signal != NULL);
 2015         assert(_real_sigaction != NULL);
 2016 //      assert(_real_exit != NULL);
 2017 
 2018         assert(_real_time != NULL);
 2019         assert(_real_stime != NULL);
 2020         assert(_real_gettimeofday != NULL);
 2021         assert(_real_settimeofday != NULL);
 2022         assert(_real_getresuid != NULL);
 2023         assert(_real_getresgid != NULL);
 2024         assert(_real_sigpending != NULL);
 2025         assert(_real_sigprocmask != NULL);
 2026         assert(_real_sched_setscheduler != NULL);
 2027         assert(_real_sched_setparam != NULL);
 2028         assert(_real_sched_getparam != NULL);
 2029         assert(_real_wait != NULL);
 2030         assert(_real_wait3 != NULL);
 2031         assert(_real_wait4 != NULL);
 2032         assert(_real_waitid != NULL);
 2033         assert(_real_waitpid != NULL);
 2034         assert(_real_statfs != NULL);
 2035         assert(_real_statfs64 != NULL);
 2036         assert(_real_fstatfs != NULL);
 2037         assert(_real_fstatfs64 != NULL);
 2038         assert(_real_link != NULL);
 2039         assert(_real_symlink != NULL);
 2040         assert(_real_unlink != NULL);
 2041         assert(_real_rename != NULL);
 2042         assert(_real_chmod != NULL);
 2043         assert(_real_readlink != NULL);
 2044         assert(_real_creat != NULL);
 2045         assert(_real_open != NULL);
 2046         assert(_real_open64 != NULL);
 2047         assert(_real_fopen != NULL);
 2048         assert(_real_fopen64 != NULL);
 2049         assert(_real_access != NULL);
 2050         assert(_real_chown != NULL);
 2051         assert(_real_lchown != NULL);
 2052         assert(_real_utime != NULL);
 2053         assert(_real_utimes != NULL);
 2054         assert(_real_llseek != NULL);
 2055         assert(_real_read != NULL);
 2056         assert(_real_fread != NULL);
 2057         assert(_real_readv != NULL);
 2058         assert(_real_write != NULL);
 2059         assert(_real_fwrite != NULL);
 2060         assert(_real_writev != NULL);
 2061         assert(_real_pread != NULL);
 2062         assert(_real_pwrite != NULL);
 2063         assert(_real_mkdir != NULL);
 2064         assert(_real_chdir != NULL);
 2065         assert(_real_rmdir != NULL);
 2066         assert(_real_setsockopt != NULL);
 2067         assert(_real_getsockopt != NULL);
 2068         assert(_real_bind != NULL);
 2069         assert(_real_connect != NULL);
 2070         assert(_real_accept != NULL);
 2071         assert(_real_getsockname != NULL);
 2072         assert(_real_getpeername != NULL);
 2073         assert(_real_send != NULL);
 2074         assert(_real_sendto != NULL);
 2075         assert(_real_sendmsg != NULL);
 2076         assert(_real_recv != NULL);
 2077         assert(_real_recvfrom != NULL);
 2078         assert(_real_recvmsg != NULL);
 2079         assert(_real_poll != NULL);
 2080         assert(_real_select != NULL);
 2081         assert(_real_pselect != NULL);
 2082         assert(_real_uname != NULL);
 2083         assert(_real_getrlimit != NULL);
 2084         assert(_real_setrlimit != NULL);
 2085         assert(_real_getrusage != NULL);
 2086         assert(_real_shmctl != NULL);
 2087         assert(_real_sysctl != NULL);
 2088 
 2089         initialBreak = currentBreak = (char *) (*_real_sbrk)(0);
 2090 
 2091         struct sigaction old_sa;
 2092         struct sigaction new_sa;
 2093         memset(&new_sa, 0, sizeof(new_sa));
 2094         new_sa.sa_sigaction = (saSigactionType *) sigsegvSigaction;
 2095         new_sa.sa_flags = SA_SIGINFO;
 2096 
 2097         dbprintf("new_sa: sa_handler %p sa_sigaction %p sa_mask %x sa_flags %x sa_restorer %p\n",
 2098                  new_sa.sa_handler,
 2099                  new_sa.sa_sigaction,
 2100                  new_sa.sa_mask,
 2101                  new_sa.sa_flags,
 2102                  new_sa.sa_restorer);
 2103 
 2104         int rc = (*_real_sigaction)(SIGSEGV, &new_sa, &old_sa);
 2105         dbprintf("sigaction(%d, %p, %p) returned %d\n", SIGSEGV, &new_sa, &old_sa, rc);
 2106         assert(rc == 0);
 2107 
 2108         dbprintf("old_sa: sa_handler %p sa_sigaction %p sa_mask %x sa_flags %x sa_restorer %p\n",
 2109                  old_sa.sa_handler,
 2110                  old_sa.sa_sigaction,
 2111                  old_sa.sa_mask,
 2112                  old_sa.sa_flags,
 2113                  old_sa.sa_restorer);
 2114 
 2115         if (old_sa.sa_flags & SA_SIGINFO)
 2116             _stored_segv_sigaction = old_sa.sa_sigaction;
 2117         else
 2118             _stored_segv_handler = old_sa.sa_handler;
 2119 
 2120         dbprintf("MemTracer init ending...\n");
 2121     }
 2122 
 2123     void addPagesSbrked(size_t start, size_t length) {
 2124         assert((length & ~PAGE_MASK) == 0);
 2125 
 2126         unsigned int page_status = PAGE_SBRK_ANON | PAGE_ON_DEMAND | PAGE_ORIG_READABLE | PAGE_ORIG_WRITABLE;
 2127 
 2128         // mprotect the pages to trap future access
 2129         if (_real_mprotect == NULL)
 2130             init_all();
 2131 
 2132         int rc = (*_real_mprotect)((void *) start, length, PROT_NONE);
 2133         assert(rc == 0);
 2134 
 2135         size_t offset = 0;
 2136         while (offset < length) {
 2137             void * page = (void *) (start + offset);
 2138             trace_printf("A 0x%08x\n", page);
 2139 
 2140             assert(_page_status_map.find(page) == _page_status_map.end());
 2141             _page_status_map[page] = page_status;
 2142 
 2143             offset += PAGE_SIZE;
 2144         }
 2145 
 2146         currentAllocatedSbrk += length;
 2147         currentSbrkUntouched += length;
 2148         if (currentAllocatedMmap + currentAllocatedSbrk > maxAllocated) {
 2149             maxAllocated = currentAllocatedMmap + currentAllocatedSbrk;
 2150         }
 2151     }
 2152 
 2153     void removePagesSbrked(size_t start, size_t length) {
 2154         assert((length & ~PAGE_MASK) == 0);
 2155 
 2156         size_t offset = 0;
 2157         while (offset < length) {
 2158             void * page = (void *) (start + offset);
 2159             trace_printf("U 0x%08x\n", page);
 2160 
 2161             // find and remove the page in the map
 2162             PageStatusMap::iterator i = _page_status_map.find(page);
 2163             assert(i != _page_status_map.end());
 2164 
 2165             if (i != _page_status_map.end()) {
 2166                 unsigned int page_status = (*i).second;
 2167 
 2168                 switch (page_status & PAGE_MAPPING_MASK) {
 2169                 case PAGE_SBRK_ANON:
 2170                     break;
 2171                 default:
 2172                     assert(false);
 2173                 }
 2174 
 2175                 switch (page_status & PAGE_STATUS_MASK) {
 2176                 case PAGE_ON_DEMAND:
 2177                     currentSbrkUntouched -= PAGE_SIZE;
 2178                     assert(currentSbrkUntouched >= 0);
 2179                     break;
 2180                 case PAGE_DISCARDED:
 2181                     currentSbrkDiscarded -= PAGE_SIZE;
 2182                     break;
 2183                 case PAGE_IN_MEMORY:
 2184                     break;
 2185                 default:
 2186                     assert(false);
 2187                 }
 2188 
 2189                 _page_status_map.erase(i);
 2190             }
 2191 
 2192             offset += PAGE_SIZE;
 2193         }
 2194 
 2195         currentAllocatedSbrk -= length;
 2196 
 2197         // remove these in the unprotected window
 2198         removePageRangeUnprotectedWindow(start, length);
 2199     }
 2200 
 2201     void handleNewBreak(char * newBreak) {
 2202         assert(newBreak >= initialBreak);
 2203 
 2204         size_t old_page_end = ((size_t) currentBreak + PAGE_SIZE - 1) & PAGE_MASK;
 2205         size_t new_page_end = ((size_t) newBreak + PAGE_SIZE - 1) & PAGE_MASK;
 2206         dbprintf("old_page_end=%p new_page_end=%p\n", old_page_end, new_page_end);
 2207 
 2208         currentBreak = newBreak;
 2209         assert(currentBreak == (*_real_sbrk)(0));
 2210 
 2211         if (new_page_end > old_page_end) {
 2212             addPagesSbrked(old_page_end, new_page_end - old_page_end);
 2213         }
 2214         else if (new_page_end < old_page_end) {
 2215             removePagesSbrked(new_page_end, old_page_end - new_page_end);
 2216         }
 2217 
 2218         currentAllocatedSbrk = currentBreak - initialBreak;
 2219         if (currentAllocatedMmap + currentAllocatedSbrk > maxAllocated) {
 2220             maxAllocated = currentAllocatedMmap + currentAllocatedSbrk;
 2221         }
 2222     }
 2223 
 2224     bool unprotectBuf(const void * buf, size_t size) {
 2225         MemTracerLock l(_lock);
 2226 
 2227         if (buf == NULL || size == 0)
 2228             return false;
 2229 
 2230         size_t start_page = (size_t) buf & PAGE_MASK;
 2231         size_t end_page = ((size_t) buf + size + PAGE_SIZE - 1) & PAGE_MASK;
 2232         assert(start_page < end_page);
 2233         bool need_to_reprotect = false;
 2234         size_t page;
 2235 
 2236         // find and remove the buffer pages in the unprotected window
 2237         removePageRangeUnprotectedWindow(start_page, end_page - start_page);
 2238 
 2239         // find the buffer pages in the map and revert their protections
 2240         page = start_page;
 2241         while (page < end_page) {
 2242             PageStatusMap::iterator i = _page_status_map.find((void *) page);
 2243             if (i != _page_status_map.end()) {
 2244                 unsigned int page_status = (*i).second;
 2245                 int prot = 0;
 2246 
 2247                 if (page_status & PAGE_ORIG_PROT_MASK) {
 2248                     if (page_status & PAGE_ORIG_READABLE)
 2249                         prot |= PROT_READ;
 2250                     if (page_status & PAGE_ORIG_WRITABLE)
 2251                         prot |= PROT_WRITE;
 2252                 }
 2253                 else {
 2254                     prot = PROT_NONE;
 2255                 }
 2256 
 2257                 // unset protections
 2258                 if (_real_mprotect == NULL)
 2259                     init_all();
 2260 
 2261                 int rc = (*_real_mprotect)((void *) page, PAGE_SIZE, prot);
 2262                 assert(rc == 0);
 2263 
 2264                 if (!need_to_reprotect)
 2265                     assert(page == start_page);
 2266                 need_to_reprotect = true;
 2267             }
 2268             else {
 2269                 assert(!need_to_reprotect);
 2270 //              break;
 2271             }
 2272             page += PAGE_SIZE;
 2273         }
 2274 
 2275         return need_to_reprotect;
 2276     }
 2277 
 2278     void reprotectBuf(const void * buf, size_t size) {
 2279         MemTracerLock l(_lock);
 2280 
 2281         size_t start_page = (size_t) buf & PAGE_MASK;
 2282         size_t end_page = ((size_t) buf + size + PAGE_SIZE - 1) & PAGE_MASK;
 2283 
 2284         // mprotect the pages to trap future access
 2285         if (_real_mprotect == NULL)
 2286             init_all();
 2287 
 2288         int rc = (*_real_mprotect)((void *) start_page, end_page - start_page, PROT_NONE);
 2289         assert(rc == 0);
 2290 
 2291         size_t page = start_page;
 2292         while (page < end_page) {
 2293             PageStatusMap::iterator i = _page_status_map.find((void *) page);
 2294             assert(i != _page_status_map.end());
 2295 
 2296             if (i != _page_status_map.end()) {
 2297                 (*i).second &= ~PAGE_CURR_PROT_MASK;
 2298             }
 2299             page += PAGE_SIZE;
 2300         }
 2301     }
 2302 
 2303     void removePageRangeUnprotectedWindow(size_t start, size_t length) {
 2304         for (int index = 0; index < UNPROTECTED_SIZE; index++) {
 2305             size_t page = (size_t) unprotectedWindow[index];
 2306             assert((page & ~PAGE_MASK) == 0);
 2307 
 2308             if (page >= start && page < start + length)
 2309                 unprotectedWindow[index] = NULL;
 2310         }
 2311     }
 2312 
 2313     void trace_printf(const char * fmt, ...) {
 2314 #if LOG_PAGE_ACCESS
 2315         if (trace_fd == 0) {
 2316             char trace_name[50];
 2317             sprintf(trace_name, "memtrace.%u.%lx", (unsigned int) getpid(), (unsigned long) pthread_self());
 2318 
 2319             if (_real_open == NULL)
 2320                 init_all();
 2321 
 2322             trace_fd = (*_real_open)(trace_name, O_CREAT | O_TRUNC | O_WRONLY | O_LARGEFILE, S_IRUSR | S_IWUSR);
 2323             if (trace_fd <= 0) {
 2324                 assert(false);
 2325                 abort();
 2326             }
 2327         }
 2328 
 2329         char buf[100];
 2330         size_t offset = 0;
 2331 
 2332 #if PRINT_TIMESTAMP
 2333         unsigned long long timestamp;
 2334         unsigned long * ts_low = (unsigned long *) &timestamp;
 2335         unsigned long * ts_hi = ts_low + 1;
 2336 
 2337         asm volatile ("rdtsc" : "=a"(*ts_low), "=d"(*ts_hi));
 2338         sprintf(buf, "%llx ", timestamp);
 2339         offset = strlen(buf);
 2340 #endif
 2341 
 2342         va_list ap;
 2343         va_start(ap, fmt);
 2344 
 2345         int n = vsnprintf(buf + offset, 100, fmt, ap);
 2346         if (n < 0 || n >= 100) {
 2347             abort();
 2348         }
 2349 
 2350         if (_real_write == NULL)
 2351             init_all();
 2352 
 2353         (*_real_write)(trace_fd, buf, offset + n);
 2354 #endif  // LOG_PAGE_ACCESS
 2355     }
 2356 
 2357     static void sigsegvSigaction(int sig_num, siginfo_t * info, void * p) {
 2358         getMemTracer()->realSigsegvSigaction(sig_num, info, p);
 2359     }
 2360 
 2361     void realSigsegvSigaction(int sig_num, siginfo_t * info, void * p) {
 2362         MemTracerLock l(_lock);
 2363 
 2364         void * page = (void *)((size_t) info->si_addr & PAGE_MASK);
 2365         dbprintf("SIGSEGV on page %p\n", page);
 2366 
 2367         PageStatusMap::iterator i = _page_status_map.find(page);
 2368 
 2369         // check if the page is in the map
 2370         if (i == _page_status_map.end()) {
 2371             // it is not us that changed its protection
 2372             dbprintf("SIGSEGV on page %p not found\n", page);
 2373             dbprintf("_stored_segv_handler=%p _stored_segv_sigaction=%p\n", _stored_segv_handler, _stored_segv_sigaction);
 2374             assert(false);
 2375 
 2376             // pass the signal to the user handler
 2377             assert(_stored_segv_handler == NULL || _stored_segv_handler == NULL);
 2378             if (_stored_segv_handler != NULL)
 2379                 (*_stored_segv_handler)(sig_num);
 2380             else if (_stored_segv_sigaction != NULL)
 2381                 (*_stored_segv_sigaction)(sig_num, info, p);
 2382         }
 2383         else {
 2384             // reset its protection
 2385             unsigned int page_status = (*i).second;
 2386             bool zero_on_demand = true;
 2387 
 2388             switch (page_status & PAGE_STATUS_MASK) {
 2389             case PAGE_ON_DEMAND:
 2390                 switch (page_status & PAGE_MAPPING_MASK) {
 2391                 case PAGE_SBRK_ANON:
 2392                     currentSbrkUntouched -= PAGE_SIZE;
 2393                     assert(currentSbrkUntouched >= 0);
 2394                     break;
 2395                 case PAGE_MMAP_ANON:
 2396                 case PAGE_MMAP_PRIVATE:
 2397                 case PAGE_MMAP_SHARED:
 2398                     currentMmapUntouched -= PAGE_SIZE;
 2399                     assert(currentMmapUntouched >= 0);
 2400                     break;
 2401                 default:
 2402                     assert(false);
 2403                 }
 2404                 page_status ^= PAGE_ON_DEMAND | PAGE_IN_MEMORY;
 2405                 break;
 2406             case PAGE_DISCARDED:
 2407                 switch (page_status & PAGE_MAPPING_MASK) {
 2408                 case PAGE_SBRK_ANON:
 2409                     currentSbrkDiscarded -= PAGE_SIZE;
 2410                     assert(currentSbrkDiscarded >= 0);
 2411                     break;
 2412                 case PAGE_MMAP_ANON:
 2413                 case PAGE_MMAP_PRIVATE:
 2414                 case PAGE_MMAP_SHARED:
 2415                     currentMmapDiscarded -= PAGE_SIZE;
 2416                     assert(currentMmapDiscarded >= 0);
 2417                     break;
 2418                 default:
 2419                     assert(false);
 2420                 }
 2421                 page_status ^= PAGE_DISCARDED | PAGE_IN_MEMORY;
 2422                 break;
 2423             case PAGE_IN_MEMORY:
 2424                 zero_on_demand = false;
 2425                 break;
 2426             default:
 2427                 assert(false);
 2428             }
 2429 
 2430 #if 0   // not distinguish reads and writes
 2431 
 2432             int rc;
 2433             int prot = 0;
 2434             assert(!(page_status & PAGE_CURR_PROT_MASK));
 2435 
 2436             // permit both read and write
 2437             if (page_status & PAGE_ORIG_PROT_MASK) {
 2438                 if (page_status & PAGE_ORIG_READABLE) {
 2439                     prot |= PROT_READ;
 2440                     page_status |= PAGE_CURR_READABLE;
 2441                 }
 2442                 if (page_status & PAGE_ORIG_WRITABLE) {
 2443                     prot |= PROT_WRITE;
 2444                     page_status |= PAGE_CURR_WRITABLE;
 2445                 }
 2446             }
 2447             else {
 2448                 prot = PROT_NONE;
 2449             }
 2450 
 2451             (*i).second = page_status;
 2452 
 2453             assert(_real_mprotect != NULL);
 2454 
 2455             rc = (*_real_mprotect)(page, PAGE_SIZE, prot);
 2456             dbprintf("mprotect(%p, %x, %x) returned %d\n", page, PAGE_SIZE, prot, rc);
 2457             assert(rc == 0);
 2458 
 2459             if (zero_on_demand)
 2460                 trace_printf("R 0x%08x\n", page);
 2461             else
 2462                 trace_printf("r 0x%08x\n", page);
 2463 
 2464             // add this page to the unprotected window and remove an old one
 2465             assert(windowPointer >= 0 && windowPointer < UNPROTECTED_SIZE);
 2466             void * old = unprotectedWindow[windowPointer];
 2467             if (old != NULL) {
 2468                 i = _page_status_map.find(old);
 2469                 if (i != _page_status_map.end()) {
 2470                     (*i).second &= ~PAGE_CURR_PROT_MASK;
 2471 
 2472                     rc = (*_real_mprotect)(old, PAGE_SIZE, PROT_NONE);
 2473                     assert(rc == 0);
 2474                 }
 2475                 else {
 2476                     dbprintf("windowPointer=%d old=%p already removed\n", windowPointer, old);
 2477                 }
 2478             }
 2479             unprotectedWindow[windowPointer] = page;
 2480             if (++windowPointer == UNPROTECTED_SIZE)
 2481                 windowPointer = 0;
 2482 
 2483 #else   // distinguish reads and writes
 2484 
 2485             int rc;
 2486             assert(!(page_status & PAGE_CURR_WRITABLE));
 2487 
 2488             if (!(page_status & PAGE_CURR_READABLE)) {
 2489                 // permit read first
 2490                 if (page_status & PAGE_ORIG_READABLE) {
 2491                     page_status |= PAGE_CURR_READABLE;
 2492                     (*i).second = page_status;
 2493                     rc = (*_real_mprotect)(page, PAGE_SIZE, PROT_READ);
 2494                     assert(rc == 0);
 2495                 }
 2496                 else {
 2497                     assert(false);
 2498                 }
 2499 
 2500                 if (zero_on_demand)
 2501                     trace_printf("R 0x%08x\n", page);
 2502                 else
 2503                     trace_printf("r 0x%08x\n", page);
 2504 
 2505                 // add this page to the unprotected window and remove an old one
 2506                 assert(windowPointer >= 0 && windowPointer < UNPROTECTED_SIZE);
 2507                 void * old = unprotectedWindow[windowPointer];
 2508                 if (old != NULL) {
 2509                     i = _page_status_map.find(old);
 2510                     if (i != _page_status_map.end()) {
 2511                         (*i).second &= ~PAGE_CURR_PROT_MASK;
 2512 
 2513                         rc = (*_real_mprotect)(old, PAGE_SIZE, PROT_NONE);
 2514                         assert(rc == 0);
 2515                     }
 2516                     else {
 2517                         dbprintf("windowPointer=%d old=%p already removed\n", windowPointer, old);
 2518                     }
 2519                 }
 2520                 unprotectedWindow[windowPointer] = page;
 2521                 if (++windowPointer == UNPROTECTED_SIZE)
 2522                     windowPointer = 0;
 2523             }
 2524             else {
 2525                 assert(page_status & PAGE_ORIG_READABLE);
 2526 
 2527                 if (page_status & PAGE_ORIG_WRITABLE) {
 2528                     page_status |= PAGE_CURR_WRITABLE;
 2529                     (*i).second = page_status;
 2530                     rc = (*_real_mprotect)(page, PAGE_SIZE, PROT_READ | PROT_WRITE);
 2531                     assert(rc == 0);
 2532                 }
 2533                 else {
 2534                     assert(false);
 2535                 }
 2536 
 2537                 if (zero_on_demand)
 2538                     trace_printf("W 0x%08x\n", page);
 2539                 else
 2540                     trace_printf("w 0x%08x\n", page);
 2541 
 2542                 // this page is already in the unprotected window
 2543             }
 2544 
 2545 #endif
 2546         }
 2547     }
 2548 
 2549     void dbprintf(const char * fmt, ...) {
 2550 #ifdef DEBUG
 2551 
 2552 #if DB_PRINT_TO_FILE
 2553         if (debug_fd == 0) {
 2554             char debug_name[50];
 2555             sprintf(debug_name, "debuglog.%d.%lx", (unsigned int) getpid(), (unsigned long) pthread_self());
 2556 
 2557             if (_real_open == NULL)
 2558                 init_all();
 2559 
 2560             debug_fd = (*_real_open)(debug_name, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
 2561             if (debug_fd <= 0)
 2562                 abort();
 2563         }
 2564 #endif
 2565 
 2566         char buf[BUF_SZ];
 2567         va_list ap;
 2568         va_start(ap, fmt);
 2569 
 2570         int n = vsnprintf(buf, BUF_SZ, fmt, ap);
 2571         if (n < 0 || n >= BUF_SZ)
 2572             abort();
 2573 
 2574 #if DB_PRINT_TO_FILE
 2575         if (_real_write == NULL)
 2576             init_all();
 2577 
 2578         (*_real_write)(debug_fd, buf, n);
 2579 #else
 2580         fprintf(stderr, "<dbprintf> %s", buf);
 2581         fflush(stderr);
 2582 #endif
 2583 
 2584 #endif  // DEBUG
 2585     }
 2586 
 2587 };  // end of class MemTracer
 2588 
 2589 __thread int MemTracer::trace_fd;
 2590 
 2591 #ifdef DEBUG
 2592 __thread int MemTracer::debug_fd;
 2593 #endif
 2594 
 2595 // these are the calls that we are having an eye on
 2596 
 2597 extern "C" {
 2598 
 2599     void * calloc(size_t nmemb, size_t size) {
 2600         return MemTracer::getMemTracer()->calloc(nmemb, size);
 2601     }
 2602 
 2603     void * malloc(size_t size) {
 2604         return MemTracer::getMemTracer()->malloc(size);
 2605     }
 2606 
 2607     void free(void * ptr) {
 2608         MemTracer::getMemTracer()->free(ptr);
 2609     }
 2610 
 2611     void * realloc(void * ptr, size_t size) {
 2612         return MemTracer::getMemTracer()->realloc(ptr, size);
 2613     }
 2614 
 2615     int brk(void * end_data_segment) {
 2616         return MemTracer::getMemTracer()->brk(end_data_segment);
 2617     }
 2618 
 2619     void * sbrk(intptr_t increment) {
 2620         return MemTracer::getMemTracer()->sbrk(increment);
 2621     }
 2622 
 2623     void * mmap(void * start, size_t length, int prot, int flags, int fd, off_t offset) {
 2624         return MemTracer::getMemTracer()->mmap(start, length, prot, flags, fd, offset);
 2625     }
 2626 
 2627     int munmap(void * start, size_t length) {
 2628         return MemTracer::getMemTracer()->munmap(start, length);
 2629     }
 2630 
 2631     int madvise(void * start, size_t length, int advice) {
 2632         return MemTracer::getMemTracer()->madvise(start, length, advice);
 2633     }
 2634     
 2635     int mprotect(void * addr, size_t len, int prot) {
 2636         return MemTracer::getMemTracer()->mprotect(addr, len, prot);
 2637     }
 2638 
 2639     sighandler_t signal(int signum, sighandler_t handler) {
 2640         return MemTracer::getMemTracer()->signal(signum, handler);
 2641     }
 2642 
 2643     int sigaction(int signum, const struct sigaction * act, struct sigaction * oldact) {
 2644         return MemTracer::getMemTracer()->sigaction(signum, act, oldact);
 2645     }
 2646 /*
 2647     void exit(int status) {
 2648         MemTracer::getMemTracer()->exit(status);
 2649     }
 2650 */
 2651 
 2652     // the following calls are intercepted merely because we need to unprotect the user buffers passed into kernel
 2653 
 2654     time_t time(time_t * t) {
 2655         return MemTracer::getMemTracer()->time(t);
 2656     }
 2657 
 2658     int stime(const time_t * t) {
 2659         return MemTracer::getMemTracer()->stime(t);
 2660     }
 2661 
 2662     int gettimeofday(struct timeval * tv, struct timezone * tz) {
 2663         return MemTracer::getMemTracer()->gettimeofday(tv, tz);
 2664     }
 2665 
 2666     int settimeofday(const struct timeval * tv, const struct timezone * tz) {
 2667         return MemTracer::getMemTracer()->settimeofday(tv, tz);
 2668     }
 2669 /*
 2670     int adjtimex(struct timex * buf) {
 2671         return MemTracer::getMemTracer()->adjtimex(buf);
 2672     }
 2673 
 2674     clock_t times(struct tms * buf) {
 2675         return MemTracer::getMemTracer()->times(buf);
 2676     }
 2677 
 2678     int nanosleep(const struct timespec * req, struct timespec * rem) {
 2679         return MemTracer::getMemTracer()->nanosleep(req, rem);
 2680     }
 2681 */
 2682     int getresuid(uid_t * ruid, uid_t * euid, uid_t * suid) {
 2683         return MemTracer::getMemTracer()->getresuid(ruid, euid, suid);
 2684     }
 2685 
 2686     int getresgid(gid_t * rgid, gid_t * egid, gid_t * sgid) {
 2687         return MemTracer::getMemTracer()->getresgid(rgid, egid, sgid);
 2688     }
 2689 /*
 2690     int getgroups(int size, gid_t list[]) {
 2691         return MemTracer::getMemTracer()->getgroups(size, list);
 2692     }
 2693 
 2694     int setgroups(size_t size, const gid_t * list) {
 2695         return MemTracer::getMemTracer()->setgroups(size, list);
 2696     }
 2697 
 2698     int acct(const char * filename) {
 2699         return MemTracer::getMemTracer()->acct(filename);
 2700     }
 2701 */
 2702     int sigpending(sigset_t * set) {
 2703         return MemTracer::getMemTracer()->sigpending(set);
 2704     }
 2705 
 2706     int sigprocmask(int how, const sigset_t * set, sigset_t * oldset) {
 2707         return MemTracer::getMemTracer()->sigprocmask(how, set, oldset);
 2708     }
 2709 /*
 2710     int getitimer(int which, struct itimerval * value) {
 2711         return MemTracer::getMemTracer()->getitimer(which, value);
 2712     }
 2713 
 2714     int setitimer(int which, const struct itimerval * value, struct itimerval * ovalue) {
 2715         return MemTracer::getMemTracer()->setitimer(which, value, ovalue);
 2716     }
 2717 
 2718     int timer_create(clockid_t clockid, struct sigevent *restrict evp,
 2719                      timer_t *restrict timerid);
 2720 
 2721     int timer_gettime(timer_t timerid, struct itimerspec *value);
 2722     int timer_settime(timer_t timerid, int flags,
 2723                       const struct itimerspec *restrict value,
 2724                       struct itimerspec *restrict ovalue);
 2725 
 2726     int clock_settime(clockid_t clk_id, const struct timespec *tp);
 2727 
 2728     int clock_gettime(clockid_t clk_id, struct timespec * tp) {
 2729         return MemTracer::getMemTracer()->clock_gettime(clk_id, tp);
 2730     }
 2731 
 2732     int clock_getres(clockid_t clk_id, struct timespec *res);
 2733     int clock_nanosleep(clockid_t clock_id, int flags,
 2734                         const struct timespec *rqtp, struct timespec *rmtp);
 2735 */
 2736     int sched_setscheduler(pid_t pid, int policy, const struct sched_param * p) {
 2737         return MemTracer::getMemTracer()->sched_setscheduler(pid, policy, p);
 2738     }
 2739 
 2740     int sched_setparam(pid_t pid, const struct sched_param * p) {
 2741         return MemTracer::getMemTracer()->sched_setparam(pid, p);
 2742     }
 2743 
 2744     int sched_getparam(pid_t pid, struct sched_param * p) {
 2745         return MemTracer::getMemTracer()->sched_getparam(pid, p);
 2746     }
 2747 /*
 2748     int sched_setaffinity(pid_t  pid,  unsigned  int  len,  unsigned  long
 2749                           *mask);
 2750 
 2751     int  sched_getaffinity(pid_t  pid,  unsigned  int  len,  unsigned long
 2752                            *mask);
 2753     int sched_rr_get_interval(pid_t pid, struct timespec *tp);
 2754 
 2755     int reboot(int magic, int magic2, int flag, void *arg);
 2756 */
 2757 
 2758 /*
 2759   asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments,
 2760                                 struct kexec_segment __user *segments,
 2761                                 unsigned long flags);
 2762 */
 2763 
 2764     pid_t wait(void * status) {
 2765         return MemTracer::getMemTracer()->wait((int *) status);
 2766     }
 2767 
 2768     pid_t wait3(void * status, int options, struct rusage * rusage) {
 2769         return MemTracer::getMemTracer()->wait3((int *) status, options, rusage);
 2770     }
 2771 
 2772     pid_t wait4(pid_t pid, void * status, int options, struct rusage * rusage) {
 2773         return MemTracer::getMemTracer()->wait4(pid, (int *) status, options, rusage);
 2774     }
 2775 
 2776     int waitid(idtype_t idtype, id_t id, siginfo_t * infop, int options) {
 2777         return MemTracer::getMemTracer()->waitid(idtype, id, infop, options);
 2778     }
 2779 
 2780     pid_t waitpid(pid_t pid, int * status, int options) {
 2781         return MemTracer::getMemTracer()->waitpid(pid, status, options);
 2782     }
 2783 
 2784 /*
 2785   asmlinkage long sys_set_tid_address(int __user *tidptr);
 2786   asmlinkage long sys_futex(u32 __user *uaddr, int op, int val, struct timespec __user *utime, u32 __user *uaddr2, int val3);
 2787 
 2788   asmlinkage long sys_init_module(void __user *umod, unsigned long len,
 2789   const char __user *uargs);
 2790   asmlinkage long sys_delete_module(const char __user *name_user,
 2791   unsigned int flags);
 2792   asmlinkage long sys_rt_sigprocmask(int how, sigset_t __user *set,
 2793   sigset_t __user *oset, size_t sigsetsize);
 2794   asmlinkage long sys_rt_sigpending(sigset_t __user *set, size_t sigsetsize);
 2795   asmlinkage long sys_rt_sigtimedwait(const sigset_t __user *uthese,
 2796   siginfo_t __user *uinfo,
 2797   const struct timespec __user *uts,
 2798   size_t sigsetsize);
 2799   asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo);
 2800 */
 2801 
 2802 /*
 2803     int  sigtimedwait(const  sigset_t  *set, siginfo_t *info, const struct
 2804                       timespec timeout);
 2805     int sigqueue(pid_t pid, int sig, const union sigval value);
 2806 
 2807     int mount(const char *source, const char *target, const char *filesys-
 2808               temtype, unsigned long mountflags, const void *data);
 2809 
 2810     int umount(const char *target);
 2811 
 2812     int umount2(const char *target, int flags);
 2813 
 2814     int truncate(const char *path, off_t length);
 2815 */
 2816 /*
 2817     int stat(const char * file_name, struct stat * buf) {
 2818         return MemTracer::getMemTracer()->stat(file_name, buf);
 2819     }
 2820 */
 2821     int statfs(const char * path, struct statfs * buf) {
 2822         return MemTracer::getMemTracer()->statfs(path, buf);
 2823     }
 2824 
 2825     int statfs64(const char * path, struct statfs64 * buf) {
 2826         return MemTracer::getMemTracer()->statfs64(path, buf);
 2827     }
 2828 
 2829 /*
 2830   asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64 __user *buf);
 2831 */
 2832 
 2833     int fstatfs(int fd, struct statfs * buf) {
 2834         return MemTracer::getMemTracer()->fstatfs(fd, buf);
 2835     }
 2836 
 2837     int fstatfs64(int fd, struct statfs64 * buf) {
 2838         return MemTracer::getMemTracer()->fstatfs64(fd, buf);
 2839     }
 2840 
 2841 /*
 2842   asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64 __user *buf);
 2843 */
 2844 /*
 2845     int lstat(const char * file_name, struct stat * buf) {
 2846         return MemTracer::getMemTracer()->lstat(file_name, buf);
 2847     }
 2848 
 2849     int fstat(int filedes, struct stat * buf) {
 2850         return MemTracer::getMemTracer()->fstat(filedes, buf);
 2851     }
 2852 */
 2853 /*
 2854   asmlinkage long sys_stat64(char __user *filename, struct stat64 __user *statbuf);
 2855   asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf);
 2856   asmlinkage long sys_lstat64(char __user *filename, struct stat64 __user *statbuf);
 2857   asmlinkage long sys_truncate64(const char __user *path, loff_t length);
 2858 */
 2859 /*
 2860     int setxattr (const char *path, const char *name,
 2861                   const void *value, size_t size, int flags);
 2862     int lsetxattr (const char *path, const char *name,
 2863                    const void *value, size_t size, int flags);
 2864     int fsetxattr (int filedes, const char *name,
 2865                    const void *value, size_t size, int flags);
 2866 
 2867     ssize_t getxattr (const char *path, const char *name,
 2868                       void *value, size_t size);
 2869     ssize_t lgetxattr (const char *path, const char *name,
 2870                        void *value, size_t size);
 2871     ssize_t fgetxattr (int filedes, const char *name,
 2872                        void *value, size_t size);
 2873 
 2874     ssize_t listxattr (const char *path,
 2875                        char *list, size_t size);
 2876     ssize_t llistxattr (const char *path,
 2877                         char *list, size_t size);
 2878     ssize_t flistxattr (int filedes,
 2879                         char *list, size_t size);
 2880     int removexattr (const char *path, const char *name);
 2881     int lremovexattr (const char *path, const char *name);
 2882     int fremovexattr (int filedes, const char *name);
 2883 
 2884     int mincore(void *start, size_t length, unsigned char *vec);
 2885 
 2886     int pivot_root(const char *new_root, const char *put_old);
 2887 
 2888     int chroot(const char *path);
 2889     int mknod(const char *pathname, mode_t mode, dev_t dev);
 2890 */
 2891     int link(const char * oldpath, const char * newpath) {
 2892         return MemTracer::getMemTracer()->link(oldpath, newpath);
 2893     }
 2894 
 2895     int symlink(const char * oldpath, const char * newpath) {
 2896         return MemTracer::getMemTracer()->symlink(oldpath, newpath);
 2897     }
 2898 
 2899     int unlink(const char * pathname) {
 2900         return MemTracer::getMemTracer()->unlink(pathname);
 2901     }
 2902 
 2903     int rename(const char * oldpath, const char * newpath) {
 2904         return MemTracer::getMemTracer()->rename(oldpath, newpath);
 2905     }
 2906 
 2907     int chmod(const char * path, mode_t mode) {
 2908         return MemTracer::getMemTracer()->chmod(path, mode);
 2909     }
 2910 
 2911 /*
 2912     long io_setup (unsigned nr_events, aio_context_t *ctxp);
 2913     long io_getevents (aio_context_t ctx_id, long min_nr, long nr,
 2914                        struct io_event *events, struct timespec *timeout);
 2915     long io_submit (aio_context_t ctx_id, long nr, struct iocb **iocbpp);
 2916     long io_cancel (aio_context_t ctx_id, struct iocb *iocb,
 2917                     struct io_event *result);
 2918     ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
 2919 */
 2920 /*
 2921   asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd,
 2922                                 loff_t __user *offset, size_t count);
 2923 */
 2924 
 2925     int readlink(const char * path, char * buf, size_t bufsiz) {
 2926         return MemTracer::getMemTracer()->readlink(path, buf, bufsiz);
 2927     }
 2928 
 2929     int creat(const char * pathname, mode_t mode) {
 2930         return MemTracer::getMemTracer()->creat(pathname, mode);
 2931     }
 2932 
 2933     int open(const char * pathname, int flags, ...) {
 2934         va_list ap;
 2935         va_start(ap, flags);
 2936         mode_t mode = va_arg(ap, mode_t);
 2937         return MemTracer::getMemTracer()->open(pathname, flags, mode);
 2938     }
 2939 
 2940     int open64(const char * pathname, int flags, ...) {
 2941         va_list ap;
 2942         va_start(ap, flags);
 2943         mode_t mode = va_arg(ap, mode_t);
 2944         return MemTracer::getMemTracer()->open64(pathname, flags, mode);
 2945     }
 2946 
 2947     FILE * fopen(const char * path, const char * mode) {
 2948         return MemTracer::getMemTracer()->fopen(path, mode);
 2949     }
 2950 
 2951     FILE * fopen64(const char * path, const char * mode) {
 2952         return MemTracer::getMemTracer()->fopen64(path, mode);
 2953     }
 2954 
 2955     int access(const char * pathname, int mode) {
 2956         return MemTracer::getMemTracer()->access(pathname, mode);
 2957     }
 2958 
 2959     int chown(const char * path, uid_t owner, gid_t group) {
 2960         return MemTracer::getMemTracer()->chown(path, owner, group);
 2961     }
 2962 
 2963     int lchown(const char * path, uid_t owner, gid_t group) {
 2964         return MemTracer::getMemTracer()->lchown(path, owner, group);
 2965     }
 2966 
 2967     int utime(const char * filename, const struct utimbuf * buf) {
 2968         return MemTracer::getMemTracer()->utime(filename, buf);
 2969     }
 2970 
 2971     int utimes(const char * filename, const struct timeval * tvp) {
 2972         return MemTracer::getMemTracer()->utimes(filename, tvp);
 2973     }
 2974 
 2975     int llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t * result, unsigned int whence) {
 2976         return MemTracer::getMemTracer()->llseek(fd, offset_high, offset_low, result, whence);
 2977     }
 2978 
 2979     ssize_t read(int fd, void * buf, size_t count) {
 2980         return MemTracer::getMemTracer()->read(fd, buf, count);
 2981     }
 2982 
 2983     size_t fread(void * ptr, size_t size, size_t nmemb, FILE * stream) {
 2984         return MemTracer::getMemTracer()->fread(ptr, size, nmemb, stream);
 2985     }
 2986 
 2987     ssize_t readv(int fd, const struct iovec * vector, int count) {
 2988         return MemTracer::getMemTracer()->readv(fd, vector, count);
 2989     }
 2990 
 2991     ssize_t write(int fd, const void * buf, size_t count) {
 2992         return MemTracer::getMemTracer()->write(fd, buf, count);
 2993     }
 2994 
 2995     size_t fwrite(const void * ptr, size_t size, size_t nmemb, FILE * stream) {
 2996         return MemTracer::getMemTracer()->fwrite(ptr, size, nmemb, stream);
 2997     }
 2998 
 2999     ssize_t writev(int fd, const struct iovec * vector, int count) {
 3000         return MemTracer::getMemTracer()->writev(fd, vector, count);
 3001     }
 3002 
 3003     ssize_t pread(int fd, void * buf, size_t count, off_t offset) {
 3004         return MemTracer::getMemTracer()->pread(fd, buf, count, offset);
 3005     }
 3006 
 3007     ssize_t pwrite(int fd, const void * buf, size_t count, off_t offset) {
 3008         return MemTracer::getMemTracer()->pwrite(fd, buf, count, offset);
 3009     }
 3010 /*
 3011     char *getcwd(char *buf, size_t size);
 3012     char *get_current_dir_name(void);
 3013     char *getwd(char *buf);
 3014 */
 3015     int mkdir(const char * pathname, mode_t mode) {
 3016         return MemTracer::getMemTracer()->mkdir(pathname, mode);
 3017     }
 3018 
 3019     int chdir(const char * path) {
 3020         return MemTracer::getMemTracer()->chdir(path);
 3021     }
 3022 
 3023     int rmdir(const char * pathname) {
 3024         return MemTracer::getMemTracer()->rmdir(pathname);
 3025     }
 3026 
 3027 /*
 3028     int lookup_dcookie(u64 cookie, char * buffer, size_t len);
 3029 
 3030     int getdents(unsigned int fd, struct dirent * dirp, unsigned int count) {
 3031         return MemTracer::getMemTracer()->getdents(fd, dirp, count);
 3032     }
 3033 */
 3034     int setsockopt(int s, int level, int optname, const void * optval, socklen_t optlen) {
 3035         return MemTracer::getMemTracer()->setsockopt(s, level, optname, optval, optlen);
 3036     }
 3037 
 3038     int getsockopt(int s, int level, int optname, void * optval, socklen_t * optlen) {
 3039         return MemTracer::getMemTracer()->getsockopt(s, level, optname, optval, optlen);
 3040     }
 3041 
 3042     int bind(int sockfd, const struct sockaddr * my_addr, socklen_t addrlen) {
 3043         return MemTracer::getMemTracer()->bind(sockfd, my_addr, addrlen);
 3044     }
 3045 
 3046     int connect(int sockfd, const struct sockaddr * serv_addr, socklen_t addrlen) {
 3047         return MemTracer::getMemTracer()->connect(sockfd, serv_addr, addrlen);
 3048     }
 3049 
 3050     int accept(int s, struct sockaddr * addr, socklen_t * addrlen) {
 3051         return MemTracer::getMemTracer()->accept(s, addr, addrlen);
 3052     }
 3053 
 3054     int getsockname(int s, struct sockaddr * name, socklen_t * namelen) {
 3055         return MemTracer::getMemTracer()->getsockname(s, name, namelen);
 3056     }
 3057 
 3058     int getpeername(int s, struct sockaddr * name, socklen_t * namelen) {
 3059         return MemTracer::getMemTracer()->getpeername(s, name, namelen);
 3060     }
 3061 
 3062     ssize_t send(int s, const void * buf, size_t len, int flags) {
 3063         return MemTracer::getMemTracer()->send(s, buf, len, flags);
 3064     }
 3065 
 3066     ssize_t sendto(int s, const void * buf, size_t len, int flags, const struct sockaddr * to, socklen_t tolen) {
 3067         return MemTracer::getMemTracer()->sendto(s, buf, len, flags, to, tolen);
 3068     }
 3069 
 3070     ssize_t sendmsg(int s, const struct msghdr * msg, int flags) {
 3071         return MemTracer::getMemTracer()->sendmsg(s, msg, flags);
 3072     }
 3073 
 3074     ssize_t recv(int s, void * buf, size_t len, int flags) {
 3075         return MemTracer::getMemTracer()->recv(s, buf, len, flags);
 3076     }
 3077 
 3078     ssize_t recvfrom(int s, void * buf, size_t len, int flags, struct sockaddr * from, socklen_t * fromlen) {
 3079         return MemTracer::getMemTracer()->recvfrom(s, buf, len, flags, from, fromlen);
 3080     }
 3081 
 3082     ssize_t recvmsg(int s, struct msghdr * msg, int flags) {
 3083         return MemTracer::getMemTracer()->recvmsg(s, msg, flags);
 3084     }
 3085 
 3086 /*
 3087     int socketpair(int d, int type, int protocol, int sv[2]);
 3088     int socketcall(int call, unsigned long *args);
 3089 */
 3090     int poll(struct pollfd * ufds, nfds_t nfds, int timeout) {
 3091         return MemTracer::getMemTracer()->poll(ufds, nfds, timeout);
 3092     }
 3093 
 3094     int select(int n, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval * timeout) {
 3095         return MemTracer::getMemTracer()->select(n, readfds, writefds, exceptfds, timeout);
 3096     }
 3097 
 3098     int pselect(int n, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, const struct timespec * timeout, const sigset_t * sigmask) {
 3099         return MemTracer::getMemTracer()->pselect(n, readfds, writefds, exceptfds, timeout, sigmask);
 3100     }
 3101 /*
 3102     int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
 3103         int  epoll_wait(int  epfd, struct epoll_event * events, int maxevents,
 3104                         int timeout)
 3105 
 3106         int gethostname(char *name, size_t len);
 3107     int sethostname(const char *name, size_t len);
 3108 
 3109     int getdomainname(char *name, size_t len);
 3110     int setdomainname(const char *name, size_t len);
 3111 */
 3112     int uname(struct utsname * buf) {
 3113         return MemTracer::getMemTracer()->uname(buf);
 3114     }
 3115 #if 0
 3116     int getrlimit(int resource, struct rlimit * rlim) {
 3117         return MemTracer::getMemTracer()->getrlimit(resource, rlim);
 3118     }
 3119 #endif
 3120     int setrlimit(int resource, const struct rlimit * rlim) {
 3121         return MemTracer::getMemTracer()->setrlimit(resource, rlim);
 3122     }
 3123 
 3124     int getrusage(int who, struct rusage * usage) {
 3125         return MemTracer::getMemTracer()->getrusage(who, usage);
 3126     }
 3127 /*
 3128     int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);
 3129 
 3130     ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msg-
 3131                    typ, int msgflg);
 3132     int msgctl(int msqid, int cmd, struct msqid_ds *buf);
 3133 */
 3134 /*
 3135     void * shmat(int shmid, const void * shmaddr, int shmflg) {
 3136         return MemTracer::getMemTracer()->shmat(shmid, shmadd, shmflg);
 3137     }
 3138 
 3139     int shmdt(const void * shmaddr) {
 3140         return MemTracer::getMemTracer()->shmdt(shmaddr);
 3141     }
 3142 */
 3143     int shmctl(int shmid, int cmd, struct shmid_ds * buf) {
 3144         return MemTracer::getMemTracer()->shmctl(shmid, cmd, buf);
 3145     }
 3146 /*
 3147     asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, str
 3148                                 uct mq_attr __user *attr);
 3149     asmlinkage long sys_mq_unlink(const char __user *name);
 3150     asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *msg_ptr, size_t
 3151                                      msg_len, unsigned int msg_prio, const struct timespec __user *abs_timeout);
 3152     asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *msg_ptr, size_t
 3153                                            msg_len, unsigned int __user *msg_prio, const struct timespec __user *abs_timeo
 3154                                            ut);
 3155     asmlinkage long sys_mq_notify(mqd_t mqdes, const struct sigevent __user *notific
 3156                                   ation);
 3157     asmlinkage long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user *mqst
 3158                                       at, struct mq_attr __user *omqstat);
 3159     asmlinkage long sys_pciconfig_read(unsigned long bus, unsigned long dfn,
 3160                                        unsigned long off, unsigned long len,
 3161                                        void __user *buf);
 3162     asmlinkage long sys_pciconfig_write(unsigned long bus, unsigned long dfn,
 3163                                         unsigned long off, unsigned long len,
 3164                                         void __user *buf);
 3165 
 3166     asmlinkage long sys_swapon(const char __user *specialfile, int swap_flags);
 3167     asmlinkage long sys_swapoff(const char __user *specialfile);
 3168 */
 3169     int sysctl(struct __sysctl_args * args) {
 3170         return MemTracer::getMemTracer()->sysctl(args);
 3171     }
 3172 /*
 3173     asmlinkage long sys_sysinfo(struct sysinfo __user *info);
 3174 
 3175     asmlinkage long sys_nfsservctl(int cmd,
 3176                                    struct nfsctl_arg __user *arg,
 3177                                    void __user *res);
 3178     asmlinkage long sys_syslog(int type, char __user *buf, int len);
 3179     asmlinkage long sys_uselib(const char __user *library);
 3180 
 3181     asmlinkage long sys_add_key(const char __user *_type,
 3182                                 const char __user *_description,
 3183                                 const void __user *_payload,
 3184                                 size_t plen,
 3185                                 key_serial_t destringid);
 3186 
 3187     asmlinkage long sys_request_key(const char __user *_type,
 3188                                     const char __user *_description,
 3189                                     const char __user *_callout_info,
 3190                                     key_serial_t destringid);
 3191 
 3192     asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
 3193                                       unsigned long maxnode);
 3194 */
 3195 }
 3196 
 3197 #endif