Skip to content
Snippets Groups Projects
Commit 9283574a authored by rtoy's avatar rtoy
Browse files

A fix for the error that causes di::handle-breakpoint to complain

about an unknown breakpoint at offset 0 when handling a function-end
breakpoint.

See the comment for compute_offset for an explanation.

Note that this seems to fix that issue, but there is still the issue
where a segfault will happen during tracing.  It seems to happen if a
GC occurs after the function end breakpoint has happened
(compute_offset has already been called before GC happens), and trace
has printed out the return value.  Then a segfault happens.

Due to some issues, this fix only works when compiled with gcc.
Compiling with Sun c produces some segfaults somewhere such that we
can't build cmucl at all.  The bizarre part is that compute_offset is
never called during a build because there are no breakpoints enabled
during a normal build.
parent 5ec1805e
No related branches found
No related tags found
No related merge requests found
/*
$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/breakpoint.c,v 1.20 2007/07/06 08:04:39 cshapiro Exp $
$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/breakpoint.c,v 1.21 2008/09/04 22:31:47 rtoy Exp $
This code was written as part of the CMU Common Lisp project at
Carnegie Mellon University, and has been placed in the public domain.
......@@ -102,6 +102,90 @@ find_code(os_context_t * scp)
}
#endif
#if defined(sparc) && defined(__GNUC__)
/*
* For some unknown reason, if you compile this code with Sun C, CMUCL
* is unable to build itself anymore. This is bizarre because this
* code is not called during a build since there are no breakpoints
* during a build.
*
* Hence, until this is figured out, we can't use this code with Sun
* C. This also means we some known issues with tracing will manifest
* itself.
*
* During a function-end-breakpoint, the pc is sometimes less than the
* code address, which bypasses the function end stuff. Then the
* offset is zero for a function-end-breakpoint, and we can't find the
* breakpoint data, causing an error during tracing. But we know this
* is a function-end breakpoint, because function_end is set to true.
*
* (This condition of pc < code address seems to occur only if a GC
* happens during tracing. I guess the function-end code object
* sometimes gets moved to a lower address than the corresponding
* code.)
*
* Hence this replacement looks at the function end flag first
* to see if it is a function-end breakpoint and does the function-end
* stuff anyway. If not, we do the normal stuff.
*/
static int
compute_offset(os_context_t * scp, lispobj code, boolean function_end)
{
if (code == NIL)
return 0;
if (function_end) {
/*
* We're in a function end breakpoint. Compute the
* offset from the (known) breakpoint location and the
* beginning of the breakpoint guts. (See *-assem.S.)
*
* Then make the offset negative so the caller knows
* that the offset is not from the code object.
*/
extern char function_end_breakpoint_trap;
extern char function_end_breakpoint_guts;
int offset;
offset =
&function_end_breakpoint_trap -
&function_end_breakpoint_guts;
#if 0
fprintf(stderr, "compute_offset\n");
fprintf(stderr, " function end offset = %d\n", offset);
#endif
return make_fixnum(-offset);
} else {
unsigned long code_start;
struct code *codeptr = (struct code *) PTR(code);
unsigned long pc = SC_PC(scp);
code_start = (unsigned long) codeptr
+ HeaderValue(codeptr->header) * sizeof(lispobj);
#if 0
fprintf(stderr, "compute_offset\n");
fprintf(stderr, " pc = %d\n", pc);
fprintf(stderr, " code_start = %d\n", code_start);
fprintf(stderr, " function_end = %d\n", function_end);
#endif
if (pc < code_start) {
return 0;
} else {
int offset = pc - code_start;
#if 0
fprintf(stderr, " offset = %d\n", offset);
fprintf(stderr, " codeptr->code_size = %d\n", codeptr->code_size);
fprintf(stderr, " function_end = %d\n", function_end);
#endif
if (offset >= codeptr->code_size) {
return 0;
} else {
return make_fixnum(offset);
}
}
}
}
#else
static int
compute_offset(os_context_t * scp, lispobj code, boolean function_end)
{
......@@ -154,6 +238,7 @@ compute_offset(os_context_t * scp, lispobj code, boolean function_end)
}
}
}
#endif
#ifndef i386
void
......@@ -165,6 +250,10 @@ handle_breakpoint(int signal, int subcode, os_context_t * scp)
code = find_code(scp);
#if 0
fprintf(stderr, "handle_breakpoint\n");
fprintf(stderr, " offset = %d\n", compute_offset(scp, code, 0));
#endif
funcall3(SymbolFunction(HANDLE_BREAKPOINT),
compute_offset(scp, code, 0), code, alloc_sap(scp));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment