[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20130418184350.GA4407@redhat.com>
Date: Thu, 18 Apr 2013 20:43:50 +0200
From: Oleg Nesterov <oleg@...hat.com>
To: Andrew Morton <akpm@...ux-foundation.org>
Cc: Alan Stern <stern@...land.harvard.edu>,
Frederic Weisbecker <fweisbec@...il.com>,
Ingo Molnar <mingo@...e.hu>,
Jan Kratochvil <jan.kratochvil@...hat.com>,
Prasad <prasad@...ux.vnet.ibm.com>, linux-kernel@...r.kernel.org
Subject: [PATCH v2 0/6] ptrace/x86: hw_breakpoints fixes/cleanups
Hello.
On top of "[PATCH 0/5] kill ptrace_{get,put}_breakpoints()".
V2:
- 2/6 was updated as Frederic suggested,
- if (!second_pass && rc)
+ if (rc && !WARN_ON(second_pass))
and the changelog was rewritten. I preserved your ack,
hopefully this is fine.
- 3-6 are new. 4/6 fixes the regression we discussed in V1.
Jan, this fixes watchpoint-zeroaddr test, but that test looks
"too simple", it doesn't check that bp actually works. I created
another test, see below.
Oleg.
------------------------------------------------------------------------------
#define _GNU_SOURCE 1
#include <stdio.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/debugreg.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <assert.h>
#include <assert.h>
#include <stddef.h>
#define DR_GLOBAL_ENABLE 0x2
#define DR_LOCAL_ENABLE 0x1
unsigned long encode_dr7(int drnum, int enable, unsigned int type, unsigned int len)
{
unsigned long dr7;
dr7 = ((len | type) & 0xf)
<< (DR_CONTROL_SHIFT + drnum * DR_CONTROL_SIZE);
if (enable)
dr7 |= (DR_GLOBAL_ENABLE << (drnum * DR_ENABLE_SIZE));
return dr7;
}
int write_dr(int pid, int dr, unsigned long val)
{
return ptrace(PTRACE_POKEUSER, pid,
offsetof (struct user, u_debugreg[dr]),
val);
}
#define GET_REG(pid, reg) \
ptrace(PTRACE_PEEKUSER, (pid), \
offsetof(struct user, regs.reg), 0)
void *get_ip(int pid)
{
return (void*)GET_REG(pid, rip);
}
void func1(void)
{
printf("HERE_1\n");
}
void func2(void)
{
printf("HERE_2\n");
}
int main(void)
{
int pid, stat;
unsigned long dr7;
pid = fork();
if (!pid) {
assert(ptrace(PTRACE_TRACEME, 0,0,0) == 0);
kill(getpid(), SIGHUP);
func1();
func2();
return 0x13;
}
assert(pid == waitpid(-1, &stat, 0));
assert(WSTOPSIG(stat) == SIGHUP);
dr7 = 0;
dr7 |= encode_dr7(0, 1, DR_RW_EXECUTE, DR_LEN_1);
dr7 |= encode_dr7(1, 1, DR_RW_EXECUTE, DR_LEN_1);
assert(write_dr(pid, 7, dr7) == 0);
assert(write_dr(pid, 0, (long)func1) == 0);
assert(write_dr(pid, 1, (long)func2) == 0);
assert(ptrace(PTRACE_CONT, pid, 0,0) == 0);
assert(pid == waitpid(-1, &stat, 0));
assert(WSTOPSIG(stat) == SIGTRAP);
assert(get_ip(pid) == func1);
assert(ptrace(PTRACE_CONT, pid, 0,0) == 0);
assert(pid == waitpid(-1, &stat, 0));
assert(WSTOPSIG(stat) == SIGTRAP);
assert(get_ip(pid) == func2);
assert(ptrace(PTRACE_CONT, pid, 0,0) == 0);
assert(pid == waitpid(-1, &stat, 0));
assert(stat == 0x1300);
return 0;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists