From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5666 invoked by alias); 8 Mar 2006 09:35:46 -0000 Received: (qmail 5657 invoked by uid 22791); 8 Mar 2006 09:35:45 -0000 X-Spam-Status: No, hits=-2.6 required=5.0 tests=BAYES_00 X-Spam-Check-By: sourceware.org Received: from fmr23.intel.com (HELO scsfmr003.sc.intel.com) (143.183.121.15) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 08 Mar 2006 09:35:43 +0000 Received: from scsfmr100.sc.intel.com (scsfmr100.sc.intel.com [10.3.253.9]) by scsfmr003.sc.intel.com (8.12.10/8.12.10/d: major-outer.mc,v 1.1 2004/09/17 17:50:56 root Exp $) with ESMTP id k289ZcEA002211; Wed, 8 Mar 2006 09:35:38 GMT Received: from [10.239.13.78] (maobb.sh.intel.com [10.239.13.78]) by scsfmr100.sc.intel.com (8.12.10/8.12.10/d: major-inner.mc,v 1.2 2004/09/17 18:05:01 root Exp $) with ESMTP id k289Zb3Y002435; Wed, 8 Mar 2006 09:35:38 GMT Message-ID: <440EA396.7000203@intel.com> Date: Wed, 08 Mar 2006 09:35:00 -0000 From: "bibo,mao" User-Agent: Thunderbird 1.5 (X11/20051201) MIME-Version: 1.0 To: prasanna@in.ibm.com CC: systemtap@sources.redhat.com Subject: Re: [PATH 1/3] User space probes-take3-RFC References: <20060306151038.GC8589@in.ibm.com> In-Reply-To: <20060306151038.GC8589@in.ibm.com> Content-Type: multipart/mixed; boundary="------------010104060304080407060400" X-Scanned-By: MIMEDefang 2.52 on 10.3.253.9 X-Virus-Checked: Checked by ClamAV on sourceware.org X-IsSubscribed: yes Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org X-SW-Source: 2006-q1/txt/msg00734.txt.bz2 This is a multi-part message in MIME format. --------------010104060304080407060400 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 3728 prasanna, I composed one example to test uprobe, it is in the attachment. And I compile uprobe.c with the command: gcc --static -g -o uprobe uprobe.c readelf --sections uprobe And in kprobe-ex.c, some environment variant need modification. #define PROBE_FILENAME "/root/test/uprobe" /* program text segment start address */ #define TEXT_START 0x8048150 /* program text segment offset */ #define TEXT_OFFSET 0x150 /* probed instruction position */ #define PROBE_POS 0x8048304 And there are some problems about current uprobe patch 1) it influences some operations about probed inode. Because there is hook function like readpage(s), when kprobe-ex.ko module is inserted, if some operation like "cp uprobe uprobe1" is executed, file uprobe1 will include inserted "int3" instruction. 2) if probed instruction cause stack vma page fault, there will be some debug information like this: void test_stack(){ int i; int p[STACK_LIMIT]; /* set user probepoint here, and default there will * be do_page_fault handler to expand stack */ p[0]=0; i=0; i++; } passed: prehandler executed BUG: sleeping function called from invalid context at mm/rmap.c:84 in_atomic():0, irqs_disabled():1 anon_vma_prepare+0x1b/0xbc release_console_sem+0x1a1/0x1a9 expand_stack+0x15/0xf1 do_page_fault+0x282/0x697 do_page_fault+0x0/0x697 error_code+0x4f/0x54 __copy_to_user_ll+0xcf/0xda uprobe_exceptions_notify+0x166/0x609 notifier_call_chain+0x15/0x25 do_int3+0x3c/0x7b int3+0x1e/0x24 passed: post handler executed 3)if probed instruction cause heap vma page fault, the applicatin will hangup. void test_heap(){ char *pchar; pchar = (char*) malloc(HEAP_LIMIT); pchar += (HEAP_LIMIT - 1); *pchar = 'c'; //set probe point here } passed: prehandler executed passed: page fault executed passed: prehandler executed BUG: scheduling while atomic: uprobe/0x00000002/7199 schedule+0x43/0x73f vprintk+0x2be/0x2f6 __wait_on_bit_lock+0x4b/0x52 __lock_page+0x69/0x70 io_schedule+0x26/0x30 sync_page+0x0/0x3b sync_page+0x38/0x3b __wait_on_bit_lock+0x2a/0x52 __lock_page+0x69/0x70 wake_bit_function+0x0/0x3c uprobe_exceptions_notify+0x36b/0x609 notifier_call_chain+0x15/0x25 do_int3+0x3c/0x7b int3+0x1e/0x24 __xfrm_policy_check+0x2a6/0x657 passed: page fault executed BUG: spinlock wrong owner on CPU#1, syslog-ng/3683 lock: c0362664, .magic: dead4ead, .owner: uprobe/7199, .owner_cpu: 0 _raw_spin_unlock+0x43/0x6c _spin_unlock_irqrestore+0x8/0xc uprobe_exceptions_notify+0x59c/0x609 notifier_call_chain+0x15/0x25 do_page_fault+0x0/0x697 do_page_fault+0x1bb/0x697 sys_stat64+0x1e/0x23 do_gettimeofday+0x31/0xda do_page_fault+0x0/0x697 error_code+0x4f/0x54 4) if probed instruction is int3, system will crash. void test_trap3() { /* set probepoint at here */ asm volatile (".byte 0xcc"); } system will crash. thanks bibo,mao Prasanna S Panchamukhi wrote: > Hi, > > Below is the take 3 of user space probes, which > seems to work for probes on applications and libraries. > Needs more testing and code review. This implementation > uses a spin lock to serialize the probe execution. > > Please provide your review comments on these patchs. > Thanks to Yanmin, Anil and Jim for their review commoments. > > Thanks > Prasanna > --------------010104060304080407060400 Content-Type: text/x-csrc; name="uprobe.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="uprobe.c" Content-length: 1961 #include #include #include #include #include #include #include #define TRAP_FLAG 0x100 # define ENTER_KERNEL "int $0x80\n\t" #define STACK_LIMIT 90000 #define HEAP_LIMIT 0x200000 void test_libfunction(const char *ori) { int result; /* set probepoint at strcmp function, when program is * loaded to run, it will load first few page into page, * and then load page on demand */ result = strcmp(ori,"1234"); } void test_stack(){ int i; int p[STACK_LIMIT]; /* set user probepoint here, and default there will * be do_page_fault handler to expand stack */ p[0]=0; i=0; i++; } void test_heap(){ char *pchar; pchar = (char*) malloc(HEAP_LIMIT); pchar += (HEAP_LIMIT - 1); *pchar = 'c'; //set probe point here } int test_dummy(int i) { return i+1; } void test_functioncall() { int i; i=0; /* set probepoint at function call point */ test_dummy(i); } void test_functionreturn() { int i; i=0; /* set probepoint at function return point */ return; } void test_trap3() { /* set probepoint at here */ asm volatile (".byte 0xcc"); } void test_syscall() { /* set probepoint at int 0x80 point */ asm volatile (ENTER_KERNEL : : "a" (20) /* getpid() */); } void my_trap(int sig) { printf("trap1 : PASS\n"); } void test_fork(){ int pid, status; char *pchar; pchar = (char*) malloc(HEAP_LIMIT); pchar += (HEAP_LIMIT - 1); pid= fork(); if (pid == 0){ /* here it will generate COW, and set probepoint here */ *pchar = 'c'; exit(0); } else{ wait(&status); } } int main() { int result,pid; int status; int i; char *pchar; signal(SIGTRAP, my_trap); /* set probepoint at i=i+1 point */ i=i+1; pchar = "12345"; test_libfunction(pchar); test_stack(); test_heap(); test_functioncall(); test_functionreturn(); test_trap3(); test_syscall(); test_fork(); printf("finished\n"); return 0; } --------------010104060304080407060400 Content-Type: text/x-csrc; name="kprobe-ex.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="kprobe-ex.c" Content-length: 1848 /*kprobe_example.c*/ #include #include #include #include #include #define PROBE_FILENAME "/root/test/uprobe" #define TEXT_START 0x8048150 #define TEXT_OFFSET 0x150 #define PROBE_POS 0x8048304 /*For each probe you need to allocate a kprobe structure*/ struct uprobe uprobe_ex; /*kprobe pre_handler: called just before the probed instruction is executed*/ int handler_pre(struct kprobe *p, struct pt_regs *regs) { printk("passed: prehandler executed \n"); return 0; } /*kprobe post_handler: called after the probed instruction is executed*/ void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags) { printk("passed: post handler executed \n"); } /* fault_handler: this is called if an exception is generated for any * instruction within the pre- or post-handler, or when Kprobes * single-steps the probed instruction. */ int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) { printk("passed: page fault executed \n"); return 0; } int init_module(void) { int ret; char *pname = PROBE_FILENAME; uprobe_ex.kp.pre_handler = handler_pre; uprobe_ex.kp.post_handler = handler_post; uprobe_ex.kp.fault_handler = handler_fault; //uprobe_ex.kp.opcode = 0; uprobe_ex.kp.addr = (kprobe_opcode_t*)PROBE_POS; uprobe_ex.offset = (PROBE_POS - TEXT_START + TEXT_OFFSET); uprobe_ex.pathname = pname; if ((ret = register_uprobe(&uprobe_ex) < 0)) { printk("register_uprobe failed, returned %d\n", ret); return -1; } printk("uprobe registered\n"); return 0; } void cleanup_module(void) { unregister_uprobe(&uprobe_ex); printk("uprobe unregistered\n"); } MODULE_LICENSE("GPL"); --------------010104060304080407060400--