public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
From: "bibo,mao" <bibo.mao@intel.com>
To: prasanna@in.ibm.com
Cc: systemtap@sources.redhat.com
Subject: Re: [PATH 1/3] User space probes-take3-RFC
Date: Wed, 08 Mar 2006 09:35:00 -0000	[thread overview]
Message-ID: <440EA396.7000203@intel.com> (raw)
In-Reply-To: <20060306151038.GC8589@in.ibm.com>

[-- Attachment #1: Type: text/plain, Size: 3728 bytes --]

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
  <c014c72f> anon_vma_prepare+0x1b/0xbc   <c011b885> 
release_console_sem+0x1a1/0x1a9
  <c0148e1f> expand_stack+0x15/0xf1   <c02bb83c> do_page_fault+0x282/0x697
  <c02bb5ba> do_page_fault+0x0/0x697   <c0103423> error_code+0x4f/0x54
  <c01adbf6> __copy_to_user_ll+0xcf/0xda   <c02ba977> 
uprobe_exceptions_notify+0x166/0x609
  <c02bbc66> notifier_call_chain+0x15/0x25   <c02ba646> do_int3+0x3c/0x7b
  <c02ba332> 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
  <c02b7dbf> schedule+0x43/0x73f   <c011be4f> vprintk+0x2be/0x2f6
  <c02b8e3f> __wait_on_bit_lock+0x4b/0x52   <c013b011> __lock_page+0x69/0x70
  <c02b8673> io_schedule+0x26/0x30   <c013b094> sync_page+0x0/0x3b
  <c013b0cc> sync_page+0x38/0x3b   <c02b8e1e> __wait_on_bit_lock+0x2a/0x52
  <c013b011> __lock_page+0x69/0x70   <c012bdf1> wake_bit_function+0x0/0x3c
  <c02bab7c> uprobe_exceptions_notify+0x36b/0x609   <c02bbc66> 
notifier_call_chain+0x15/0x25
  <c02ba646> do_int3+0x3c/0x7b   <c02ba332> int3+0x1e/0x24
  <c02b007b> __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
  <c01ae774> _raw_spin_unlock+0x43/0x6c   <c02ba14a> 
_spin_unlock_irqrestore+0x8/0xc
  <c02badad> uprobe_exceptions_notify+0x59c/0x609   <c02bbc66> 
notifier_call_chain+0x15/0x25
  <c02bb5ba> do_page_fault+0x0/0x697   <c02bb775> do_page_fault+0x1bb/0x697
  <c015f786> sys_stat64+0x1e/0x23   <c01344ae> do_gettimeofday+0x31/0xda
  <c02bb5ba> do_page_fault+0x0/0x697   <c0103423> 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
> 

[-- Attachment #2: uprobe.c --]
[-- Type: text/x-csrc, Size: 1961 bytes --]

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

#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;
}


[-- Attachment #3: kprobe-ex.c --]
[-- Type: text/x-csrc, Size: 1848 bytes --]

/*kprobe_example.c*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
#include <linux/sched.h>

#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");


  parent reply	other threads:[~2006-03-08  9:35 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-03-06 15:09 Prasanna S Panchamukhi
2006-03-06 15:10 ` [PATH 2/3] User space probes-readpage hooks take3-RFC Prasanna S Panchamukhi
2006-03-06 15:11   ` [PATH 3/3] User space probes-single stepping out-of-line take3-RFC Prasanna S Panchamukhi
2006-03-08  9:35 ` bibo,mao [this message]
2006-03-10 13:59   ` [PATH 1/3] User space probes-take3-RFC Prasanna S Panchamukhi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=440EA396.7000203@intel.com \
    --to=bibo.mao@intel.com \
    --cc=prasanna@in.ibm.com \
    --cc=systemtap@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).