Back to index

php5  5.3.10
fpm_trace_mach.c
Go to the documentation of this file.
00001 
00002        /* $Id: fpm_trace_mach.c,v 1.4 2008/08/26 15:09:15 anight Exp $ */
00003        /* (c) 2007,2008 Andrei Nigmatulin */
00004 
00005 #include "fpm_config.h"
00006 
00007 #include <mach/mach.h>
00008 #include <mach/mach_vm.h>
00009 
00010 #include <unistd.h>
00011 
00012 #include "fpm_trace.h"
00013 #include "fpm_process_ctl.h"
00014 #include "fpm_unix.h"
00015 #include "zlog.h"
00016 
00017 
00018 static mach_port_name_t target;
00019 static vm_offset_t target_page_base;
00020 static vm_offset_t local_page;
00021 static mach_msg_type_number_t local_size;
00022 
00023 static void fpm_mach_vm_deallocate() /* {{{ */
00024 {
00025        if (local_page) {
00026               mach_vm_deallocate(mach_task_self(), local_page, local_size);
00027               target_page_base = 0;
00028               local_page = 0;
00029               local_size = 0;
00030        }
00031 }
00032 /* }}} */
00033 
00034 static int fpm_mach_vm_read_page(vm_offset_t page) /* {{{ */
00035 {
00036        kern_return_t kr;
00037 
00038        kr = mach_vm_read(target, page, fpm_pagesize, &local_page, &local_size);
00039        if (kr != KERN_SUCCESS) {
00040               zlog(ZLOG_ERROR, "failed to read vm page: mach_vm_read(): %s (%d)", mach_error_string(kr), kr);
00041               return -1;
00042        }
00043        return 0;
00044 }
00045 /* }}} */
00046 
00047 int fpm_trace_signal(pid_t pid) /* {{{ */
00048 {
00049        if (0 > fpm_pctl_kill(pid, FPM_PCTL_STOP)) {
00050               zlog(ZLOG_SYSERROR, "failed to send SIGSTOP to %d", pid);
00051               return -1;
00052        }
00053        return 0;
00054 }
00055 /* }}} */
00056 
00057 int fpm_trace_ready(pid_t pid) /* {{{ */
00058 {
00059        kern_return_t kr;
00060 
00061        kr = task_for_pid(mach_task_self(), pid, &target);
00062        if (kr != KERN_SUCCESS) {
00063               char *msg = "";
00064 
00065               if (kr == KERN_FAILURE) {
00066                      msg = " It seems that master process does not have enough privileges to trace processes.";
00067               }
00068               zlog(ZLOG_ERROR, "task_for_pid() failed: %s (%d)%s", mach_error_string(kr), kr, msg);
00069               return -1;
00070        }
00071        return 0;
00072 }
00073 /* }}} */
00074 
00075 int fpm_trace_close(pid_t pid) /* {{{ */
00076 {
00077        fpm_mach_vm_deallocate();
00078        target = 0;
00079        return 0;
00080 }
00081 /* }}} */
00082 
00083 int fpm_trace_get_long(long addr, long *data) /* {{{ */
00084 {
00085        size_t offset = ((uintptr_t) (addr) % fpm_pagesize);
00086        vm_offset_t base = (uintptr_t) (addr) - offset;
00087 
00088        if (base != target_page_base) {
00089               fpm_mach_vm_deallocate();
00090               if (0 > fpm_mach_vm_read_page(base)) {
00091                      return -1;
00092               }
00093        }
00094        *data = * (long *) (local_page + offset);
00095        return 0;
00096 }
00097 /* }}} */
00098 
00099