Subject: Re: SIGTRAP for traced processes and COMPAT_MACH
To: Jaromir Dolecek <jdolecek@NetBSD.org>
From: Emmanuel Dreyfus <manu@netbsd.org>
List: tech-kern
Date: 11/27/2003 20:25:30
Jaromir Dolecek <jdolecek@NetBSD.org> wrote:
> I'd propose to first confirm that Darwin/MacOSX really delivers the
> exception even when the appropriate signal is blocked. If no, end
> of story and we don't need to do anything special.
It really does. Why do you doubt it? Darwin's kernel is just a non UNIX kernel
with a BSD API on the top of it. Mach doesn't care about signal masks, it does
not even know what it is.
Consider the following program:
#include <mach/mach_types.h>
#include <mach/task.h>
#include <mach/mach.h>
#include <mach/message.h>
#include <stdio.h>
#include <ctype.h>
#include <pthread.h>
#include <signal.h>
void dump(char *data, size_t len) {
int i, j;
for (i = 0; i < len; i += 16) {
printf("%p ", &data[i]);
for (j = i; j < i + 16; j += 4)
printf("0x%08x ", *((int *)(&data[j])));
printf(" ");
for (j = i; j < i + 16; j++)
if (isprint(data[j]))
printf("%c", data[j]);
else
printf(".");
printf("\n");
}
return;
}
void
start(void) {
task_t me;
printf("thread running\n");
me = mach_task_self();
printf("child trying to raise an exception...\n");
*(int *)(0xffffffff) = 0x1234567;
printf("child exit\n");
return;
}
int
main(void) {
task_t me;
mach_port_t exc;
kern_return_t err;
char buf[1024];
mach_msg_header_t *msgh;
mach_msg_return_t ret;
pthread_t th;
sigset_t sigset;
me = mach_task_self();
printf("me = %x\n", me);
err = mach_port_allocate(me, MACH_PORT_RIGHT_RECEIVE, &exc);
printf("err = %x, exc = %x\n", err, exc);
err = mach_port_insert_right(me, exc, exc,
MACH_MSG_TYPE_MAKE_SEND);
printf("err = %x, exc = %x\n", err, exc);
err = task_set_exception_ports(me,
EXC_MASK_BAD_ACCESS, exc, EXCEPTION_DEFAULT, 1);
printf("err = %x\n", err);
sigemptyset(&sigset);
sigaddset(&sigset, SIGSEGV);
err = sigprocmask(SIG_BLOCK, &sigset, NULL);
printf("err = %d\n", err);
err = pthread_create(&th, NULL, (void *)start, NULL);
sleep(1);
printf("ready to receive an exception\n");
msgh = (mach_msg_header_t *)&buf[0];
msgh->msgh_bits = 0;
msgh->msgh_size = 1024;
msgh->msgh_remote_port = 0;
msgh->msgh_local_port = exc;
msgh->msgh_id = 0;
ret = mach_msg_receive(msgh);
printf("ret = %x\n", ret);
dump((char *)msgh, msgh->msgh_size);
return 0;
}
$ ./excsignal
me = 103
err = 0, exc = 907
err = 0, exc = 907
err = 0
err = 0
thread running
child trying to raise an exception...
ready to receive an exception
ret = 0
0xbffff9a0 0x80001112 0x0000004c 0x00000c03 0x00000907 .......L........
0xbffff9b0 0x0d9a3940 0x00000961 0x00000002 0x00000b03 ..9@...a........
0xbffff9c0 0x0d9a3960 0x24481100 0x00000103 0x0217280b ..9`$H........(.
0xbffff9d0 0x00001100 0x00000000 0x00000000 0x00000001 ................
0xbffff9e0 0x00000002 0x00000001 0xffffffff 0x00000000 ................
--
Emmanuel Dreyfus
Il y a 10 sortes de personnes dans le monde: ceux qui comprennent
le binaire et ceux qui ne le comprennent pas.
manu@netbsd.org