All of lore.kernel.org
 help / color / mirror / Atom feed
* [Resend] ia64 find thread for user rbs address
@ 2007-01-30  3:02 bibo,mao
  0 siblings, 0 replies; only message in thread
From: bibo,mao @ 2007-01-30  3:02 UTC (permalink / raw)
  To: linux-ia64

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

hi,
  I encountered one problem when running ptrace test case which
is in the attachment, the situation is this: traced process's
syscall parameter needs to be accessed, but for sys_clone system
call with clone_flag (CLONE_VFORK | CLONE_VM | SIGCHLD) parameter.
This syscall's parameter accessing result is wrong.

  The reason is that vforked child process mm point is the same,
but tgid is different. Without this patch find_thread_for_addr
will return vforked process if vforked process is also stopped,
but not the thread which calls vfork syscall.

thanks
bibo,mao

------------------------------------------------------------------
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index aa705e4..2131db4 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -607,7 +607,7 @@ find_thread_for_addr (struct task_struct
 	 */
  	list_for_each_safe(this, next, &current->children) {
 		p = list_entry(this, struct task_struct, sibling);
-		if (p->mm != mm)
+		if (p->tgid != child->tgid)
 			continue;
 		if (thread_matches(p, addr)) {
 			child = p;

[-- Attachment #2: vfork.c --]
[-- Type: text/plain, Size: 3350 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sched.h>
#include <asm/rse.h>
//#include <asm/ptrace.h>
#include <asm/ptrace_offsets.h>

#define PTRACE_EVENT_FORK 1
#define PTRACE_EVENT_VFORK 2
#define PTRACE_EVENT_CLONE 3
#define PTRACE_EVENT_EXEC 4
#define PTRACE_EVENT_VFORK_DONE 5
#define PTRACE_EVENT_EXIT 6
#define PTRACE_SETOPTIONS 0x4200
#define PTRACE_GETEVENTMSG 0x4201
#define PTRACE_O_TRACESYSGOOD 0x00000001
#define PTRACE_O_TRACEFORK 0x00000002
#define PTRACE_O_TRACEVFORK 0x00000004
#define PTRACE_O_TRACECLONE 0x00000008
#define PTRACE_O_TRACEEXEC 0x00000010
#define PTRACE_O_TRACEVFORKDONE 0x00000020
#define PTRACE_O_TRACEEXIT 0x00000040
#define PALL PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE \
	| PTRACE_O_TRACEEXEC | PTRACE_O_TRACEVFORKDONE | PTRACE_O_TRACEEXIT

void fetch_clone_flags(pid_t pid, unsigned long* clone_flags)
{
	struct pt_all_user_regs ptregs;
	unsigned long bsp, cfm, sof, sol;
	unsigned long addr;
	long ret;

	ret = ptrace(PTRACE_GETREGS, pid, 0, (unsigned long)&ptregs);
	bsp = ptrace (PTRACE_PEEKUSER, pid, PT_AR_BSP, 0);
	cfm = ptrace (PTRACE_PEEKUSER, pid, PT_CFM, 0);
	sof = (cfm >> 0) & 0x7f;
	sol = (cfm >> 7) & 0x7f;
	bsp = (unsigned long) ia64_rse_skip_regs((void *) bsp, -sof + sol);
	addr= (unsigned long) ia64_rse_skip_regs((void *) bsp, 0);
	ret = ptrace (PTRACE_PEEKTEXT, pid, addr, (unsigned long) clone_flags);
	*clone_flags = ret;
}

/* Wrapper function for waitpid which handles EINTR.  */
static int my_waitpid (int pid, int *status, int flags)
{
  int ret;
  int old_status = status ? *status : 0;
  do {
      ret = waitpid (pid, status, flags);
    }
  while (ret == -1 && errno == EINTR);

  if (ret == 0 && status != 0) 
      *status = old_status;

  return ret;
}

int main() {
	unsigned long pid, npid ;
	int status, event,ret, child_status;
	char *stack ;
	unsigned long clone_flags;

	pid = fork();
	if(pid == 0)
	{
		ptrace(PTRACE_TRACEME,0,NULL,NULL) ;
		kill (getpid (), SIGSTOP);
		if (vfork() == 0){
			execve("/bin/true",NULL,NULL) ;
		}
		exit(0) ;
	}

	ret =  my_waitpid(pid, &status, 0);
	if (!WIFSTOPPED(status)) {
		perror("waitpid failed unexpected tstatus \n");
		return -1;
	}
	if (ptrace(PTRACE_SETOPTIONS,pid,NULL,PALL) < 0) {
		perror("PTRACE_SETOPTIONS not supported\n");
		return -1;
	}
	if (ptrace(PTRACE_CONT,pid,0,0) < 0) {
		perror("PTRACE_CONT \n");
		return -1;
	}
	if ( my_waitpid(pid,&status,0) < 0) {
		perror("wait4 failed");
		return -1;
	}
	event = (status >> 16) & 0xffff ;
	if (event == PTRACE_EVENT_FORK 
	    || event == PTRACE_EVENT_VFORK
	    || event == PTRACE_EVENT_CLONE) {
		if (ptrace(PTRACE_GETEVENTMSG,pid,NULL,&npid) < 0) {
			perror("PTRACE_GETEVENTMSG\n");
			return -1;
		}
		sleep(1);
		fetch_clone_flags(pid, &clone_flags);
		if (clone_flags == (CLONE_VFORK | CLONE_VM | SIGCHLD))
			printf("PTRACE_PEEKUSER succeed\n");	
		else
			printf("PTRACE_PEEKUSER failed\n");	
		if (my_waitpid(npid,&child_status,0) < 0) {
			perror("waitpid \n"); 
			return -1;
		}
		ptrace (PTRACE_KILL, npid, 0, 0);
		ptrace (PTRACE_KILL, pid, 0, 0); 
		//ptrace(PTRACE_CONT, npid, 0, WSTOPSIG(child_status));
		//ptrace(PTRACE_CONT, pid, 0, WSTOPSIG(status));
		my_waitpid(-1,&status,0);
	} 
	return 0 ;
}

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2007-01-30  3:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-30  3:02 [Resend] ia64 find thread for user rbs address bibo,mao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.