linux/arch
Chuck Ebbert 635cf99a80 [PATCH] i386: fix singlestep through an int80 syscall
Using PTRACE_SINGLESTEP on a child that does an int80 syscall misses the
SIGTRAP that should be delivered upon syscall exit.  Fix that by setting
TIF_SINGLESTEP when entering the kernel via int80 with TF set.

/* Test whether singlestep through an int80 syscall works.
 */
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <asm/user.h>

static int child, status;
static struct user_regs_struct regs;

static void do_child()
{
	ptrace(PTRACE_TRACEME, 0, 0, 0);
	kill(getpid(), SIGUSR1);
	asm ("int $0x80" : : "a" (20)); /* getpid */
}

static void do_parent()
{
	unsigned long eip, expected = 0;
again:
	waitpid(child, &status, 0);
	if (WIFEXITED(status) || WIFSIGNALED(status))
		return;

	if (WIFSTOPPED(status)) {
		ptrace(PTRACE_GETREGS, child, 0, &regs);
		eip = regs.eip;
		if (expected)
			fprintf(stderr, "child stop @ %08x, expected %08x %s\n",
					eip, expected,
					eip == expected ? "" : " <== ERROR");

		if (*(unsigned short *)eip == 0x80cd) {
			fprintf(stderr, "int 0x80 at %08x\n", (unsigned int)eip);
			expected = eip + 2;
		} else
			expected = 0;

		ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
	}
	goto again;
}

int main(int argc, char * const argv[])
{
	child = fork();
	if (child)
		do_parent();
	else
		do_child();
	return 0;
}

Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-03-23 07:38:05 -08:00
..
alpha [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00
arm Merge master.kernel.org:/home/rmk/linux-2.6-arm 2006-03-22 17:32:09 -08:00
arm26 [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00
cris [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00
frv [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00
h8300 [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00
i386 [PATCH] i386: fix singlestep through an int80 syscall 2006-03-23 07:38:05 -08:00
ia64 [PATCH] hugepage: is_aligned_hugepage_range() cleanup 2006-03-22 07:54:04 -08:00
m32r [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00
m68k [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00
m68knommu [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00
mips [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00
parisc [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00
powerpc Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc 2006-03-22 22:20:46 -08:00
ppc Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc 2006-03-22 22:20:46 -08:00
s390 [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00
sh [PATCH] hugepage: is_aligned_hugepage_range() cleanup 2006-03-22 07:54:04 -08:00
sh64 [PATCH] hugepage: is_aligned_hugepage_range() cleanup 2006-03-22 07:54:04 -08:00
sparc Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6 2006-03-22 10:56:57 -08:00
sparc64 [PATCH] sparc64: fix set_page_count merge clash 2006-03-23 07:15:21 -08:00
um [PATCH] x86: SMP alternatives 2006-03-23 07:38:04 -08:00
v850 [PATCH] add EXPORT_SYMBOL_GPL_FUTURE() 2006-03-20 13:42:58 -08:00
x86_64 [PATCH] x86: early_printk(): remove MAX_YPOS and MAX_XPOS macros 2006-03-23 07:38:05 -08:00
xtensa [PATCH] remove set_page_count() outside mm/ 2006-03-22 07:54:02 -08:00