problem stepping across an EXC_BAD_ACCESS in gdb
problem stepping across an EXC_BAD_ACCESS in gdb
- Subject: problem stepping across an EXC_BAD_ACCESS in gdb
- From: Cyrus Harmon <email@hidden>
- Date: Thu, 2 Mar 2006 11:58:10 -0800
Dear xcode-users,
[This was originally sent to unix-porting, but it was suggested there
that I take this here]
I've been having trouble stepping across an EXC_BAD_ACCESS in gdb.
I've attached a test case at the end of this but to fend off the
notion that this is a silly thing to do, I'm working on a language
environment that uses protected memory as a core feature of its
garbage collection process. The expectation is that the OS will
provide a memory protection mechanism and a way to have signal
handlers run when, for instance, one tries to dereference a pointer
into the protected memory block. This part works, thankfully, but gdb
on both powerpc and intel macos 10.4.5 with the latest xcode tools
breaks this.
I expect to be able to run my program from and preferably both be
able to continue across an EXC_BAD_ACCESS signal or to ignore these
with handle pass noprint. Unfortunately, neither of these approaches
work on either flavor of MacOS, but generally work on other unix
environments, including linux/ppc and linux/x86-64.
The test code attached demonstrates the problem. To reproduce,
compile this and run it from gdb. I get:
Reading symbols for shared libraries . done
foo starts at: 0x1800400
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x01801000
0x00001f05 in main ()
(gdb) c
Continuing.
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x01801000
0x00001f05 in main ()
(gdb) c
Continuing.
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x01801000
0x00001f05 in main ()
(gdb) c
Continuing.
.... and so on
When I try handle pass noprint EXC_BAD_ACCESS it just hangs.
I would greatly appreciate any suggestions (besides rewriting the
whole thing to use mach exceptions, there's no reason Unix signals
can't do this job) or workarounds. I didn't mean to give the
impression that I am opposed to a workaround involving mach
exceptions, but I'd rather not have to change the whole architecture
of the signal handling to support darwin. If a mach exception handler
can be used in conjunction with the existing architecture to make gdb
happy, I'm happy to explore that.
Thanks,
Cyrus
#include <stdio.h>
#include <stddef.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/types.h>
#include <unistd.h>
#if defined(__MACH__)
#define SIG_MEMORY_FAULT SIGBUS
#include <sys/_types.h>
#include <sys/ucontext.h>
#elif defined(__linux)
#define __USE_GNU
#include <sys/ucontext.h>
#undef __USE_GNU
#define SIG_MEMORY_FAULT SIGSEGV
#else
#error "Add support for this OS!"
#endif
#include <sys/mman.h>
#include <setjmp.h>
#include <stdlib.h>
#include <limits.h>
#define PAGESIZE 4096
typedef struct ucontext os_context_t;
static int* addr_from_context = NULL;
static os_context_t* void_context = NULL;
static struct mcontext *machine_context = NULL;
static int* eip = NULL;
static int* foo = NULL;
static int flags;
void sigbus_handler(int signal, siginfo_t* my_siginfo, void* my_context)
{
addr_from_context = (int*) my_siginfo->si_addr;
void_context = (os_context_t*) my_context;
machine_context = (struct mcontext *) &(void_context-
>uc_mcontext);
#if defined(__MACH__)
eip = (int*) (void_context->uc_mcontext->ss.eip);
flags = void_context->uc_mcontext->ss.eflags;
#elif defined(__linux__) && defined(__x86_64__)
eip = (int*) (void_context->uc_mcontext.gregs[REG_RIP]);
flags = void_context->uc_mcontext.gregs[REG_EFL];
#endif
mprotect(foo, 1024, PROT_READ | PROT_WRITE);
}
void pc_test_1() {
int bar;
mprotect(foo,1024,PROT_NONE);
printf("pc test 1\n");
bar = *foo;
printf("eip: %p\n", (void*)eip);
printf("flags: %x\n", flags);
mprotect(foo,1024,PROT_NONE);
}
void pc_test_2() {
int bar;
mprotect(foo,1024,PROT_NONE);
printf("pc test 2\n");
bar = *foo;
printf("eip: %p\n", (void*)eip);
printf("flags: %x\n", flags);
mprotect(foo,1024,PROT_NONE);
}
int main(int argc, char** argv)
{
int bar;
struct sigaction sa;
sa.sa_sigaction = sigbus_handler;
sa.sa_flags = SA_SIGINFO | SA_RESTART;
sigaction(SIG_MEMORY_FAULT, &sa, NULL);
foo = (int*) malloc(1024 + PAGESIZE - 1);
printf("foo starts at: %p\n", (void*)foo);
foo = (int*)(((long) foo + PAGESIZE - 1) & ~(PAGESIZE - 1));
mprotect(foo,1024,PROT_NONE);
bar = *foo;
printf("addr_from_context: %p vs foo: %p\n", (void*)
addr_from_context, (void*)foo);
pc_test_1();
pc_test_2();
return 0;
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden