/[cmucl]/src/lisp/breakpoint.c
ViewVC logotype

Diff of /src/lisp/breakpoint.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.20 by cshapiro, Fri Jul 6 08:04:39 2007 UTC revision 1.20.6.1 by rtoy, Sun Nov 2 13:30:03 2008 UTC
# Line 24  Line 24 
24  #endif  #endif
25    
26  /*  /*
27   * See MAKE-BOGUS-LRA in code/debug-int.lisp for these values.  (We   * See MAKE-BOGUS-LRA in code/debug-int.lisp for these values.
28   * really should generate these from the Lisp code.)   *
29     * Ideally, internals.h should have the correct values.  We leave
30     * these defaults here for now.
31   */   */
32    #ifndef REAL_LRA_SLOT
33  #define REAL_LRA_SLOT 0  #define REAL_LRA_SLOT 0
34    #endif
35    
36    #ifndef KNOWN_RETURN_P_SLOT
37  #ifndef i386  #ifndef i386
38  #define KNOWN_RETURN_P_SLOT 1  #define KNOWN_RETURN_P_SLOT 1
 #define BOGUS_LRA_CONSTANTS 2  
39  #else  #else
40  #define KNOWN_RETURN_P_SLOT 2  #define KNOWN_RETURN_P_SLOT 2
41    #endif
42    #endif
43    
44    #ifndef BOGUS_LRA_CONSTANTS
45    #ifndef i386
46    #define BOGUS_LRA_CONSTANTS 2
47    #else
48  #define BOGUS_LRA_CONSTANTS 3  #define BOGUS_LRA_CONSTANTS 3
49  #endif  #endif
50    #endif
51    
52    
53  static void *  static void *
54  compute_pc(lispobj code_obj, int pc_offset)  compute_pc(lispobj code_obj, int pc_offset)
# Line 102  find_code(os_context_t * scp) Line 116  find_code(os_context_t * scp)
116  }  }
117  #endif  #endif
118    
119    #if (defined(DARWIN) && defined(__ppc__)) || (defined(sparc))
120    /*
121     * During a function-end-breakpoint, the pc is sometimes less than the
122     * code address, which bypasses the function end stuff.  Then the
123     * offset is zero for a function-end-breakpoint, and we can't find the
124     * breakpoint data, causing an error during tracing.  But we know this
125     * is a function-end breakpoint, because function_end is set to true.
126     *
127     * (This condition of pc < code address seems to occur only if a GC
128     * happens during tracing.  I guess the function-end code object
129     * sometimes gets moved to a lower address than the corresponding
130     * code.)
131     *
132     * Hence this replacement looks at the function end flag first
133     * to see if it is a function-end breakpoint and does the function-end
134     * stuff anyway.  If not, we do the normal stuff.
135     */
136    static int
137    compute_offset(os_context_t * scp, lispobj code, boolean function_end)
138    {
139        if (code == NIL)
140            return 0;
141        if (function_end) {
142            /*
143             * We're in a function end breakpoint.  Compute the
144             * offset from the (known) breakpoint location and the
145             * beginning of the breakpoint guts.  (See *-assem.S.)
146             *
147             * Then make the offset negative so the caller knows
148             * that the offset is not from the code object.
149             */
150            extern char function_end_breakpoint_trap;
151            extern char function_end_breakpoint_guts;
152            int offset;
153    
154            offset =
155                &function_end_breakpoint_trap -
156                &function_end_breakpoint_guts;
157    #if 0
158            fprintf(stderr, "compute_offset\n");
159            fprintf(stderr, " function end offset  = %d\n", offset);
160    #endif
161            return make_fixnum(-offset);
162        } else {
163            unsigned long code_start;
164            struct code *codeptr = (struct code *) PTR(code);
165            unsigned long pc = SC_PC(scp);
166    
167            code_start = (unsigned long) codeptr
168                + HeaderValue(codeptr->header) * sizeof(lispobj);
169    #if 0
170            fprintf(stderr, "compute_offset\n");
171            fprintf(stderr, " pc = %d\n", pc);
172            fprintf(stderr, " code_start = %d\n", code_start);
173            fprintf(stderr, " function_end = %d\n", function_end);
174    #endif
175            if (pc < code_start) {
176                return 0;
177            } else {
178                int offset = pc - code_start;
179    
180    #if 0
181                fprintf(stderr, " offset = %d\n", offset);
182                fprintf(stderr, " codeptr->code_size = %d\n", codeptr->code_size);
183                fprintf(stderr, " function_end = %d\n", function_end);
184    #endif
185                if (offset >= codeptr->code_size) {
186                    return 0;
187                } else {
188                    return make_fixnum(offset);
189                }
190            }
191        }
192    }
193    #else
194  static int  static int
195  compute_offset(os_context_t * scp, lispobj code, boolean function_end)  compute_offset(os_context_t * scp, lispobj code, boolean function_end)
196  {  {
# Line 125  compute_offset(os_context_t * scp, lispo Line 214  compute_offset(os_context_t * scp, lispo
214              int offset = pc - code_start;              int offset = pc - code_start;
215    
216              if (offset >= codeptr->code_size) {              if (offset >= codeptr->code_size) {
217                  if (function_end) {                  return 0;
 #if defined(sparc) || (defined(DARWIN) && defined(__ppc__))  
                     /*  
                      * 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;  
   
                     offset =  
                         &function_end_breakpoint_trap -  
                         &function_end_breakpoint_guts;  
                     return make_fixnum(-offset);  
 #else  
                     return 0;  
 #endif  
                 } else {  
                     return 0;  
                 }  
218              } else {              } else {
219                  return make_fixnum(offset);                  return make_fixnum(offset);
220              }              }
221          }          }
222      }      }
223  }  }
224    #endif
225    
226  #ifndef i386  #ifndef i386
227  void  void
# Line 165  handle_breakpoint(int signal, int subcod Line 233  handle_breakpoint(int signal, int subcod
233    
234      code = find_code(scp);      code = find_code(scp);
235    
236    #if 0
237        fprintf(stderr, "handle_breakpoint\n");
238        fprintf(stderr, " offset = %d\n", compute_offset(scp, code, 0));
239    #endif
240      funcall3(SymbolFunction(HANDLE_BREAKPOINT),      funcall3(SymbolFunction(HANDLE_BREAKPOINT),
241               compute_offset(scp, code, 0), code, alloc_sap(scp));               compute_offset(scp, code, 0), code, alloc_sap(scp));
242    
# Line 200  handle_function_end_breakpoint(int signa Line 272  handle_function_end_breakpoint(int signa
272      lispobj code, lra;      lispobj code, lra;
273      struct code *codeptr;      struct code *codeptr;
274      int offset;      int offset;
275        int known_return_p;
276    
277      fake_foreign_function_call(scp);      fake_foreign_function_call(scp);
278    
279      code = find_code(scp);      code = find_code(scp);
# Line 231  handle_function_end_breakpoint(int signa Line 304  handle_function_end_breakpoint(int signa
304           * Some magic here.  pc points to the trap instruction.  The           * Some magic here.  pc points to the trap instruction.  The
305           * offset gives us where the function_end_breakpoint_guts           * offset gives us where the function_end_breakpoint_guts
306           * begins.  But we need to back up some more to get to the           * begins.  But we need to back up some more to get to the
307           * code-component object.  The magic 2 below is           * code-component object.  See MAKE-BOGUS-LRA in
308             * debug-int.lisp
309           */           */
310          code = pc - fixnum_value(offset);          code = pc - fixnum_value(offset);
311          code -= sizeof(struct code) + BOGUS_LRA_CONSTANTS * sizeof(lispobj);          code -= sizeof(struct code) + BOGUS_LRA_CONSTANTS * sizeof(lispobj);
# Line 246  handle_function_end_breakpoint(int signa Line 320  handle_function_end_breakpoint(int signa
320  #endif  #endif
321      }      }
322    
     funcall3(SymbolFunction(HANDLE_BREAKPOINT), offset, code, alloc_sap(scp));  
   
     /*  
      * Breakpoint handling done, so get the real LRA where we're  
      * supposed to return to so we can return there.  
      */  
323      lra = codeptr->constants[REAL_LRA_SLOT];      lra = codeptr->constants[REAL_LRA_SLOT];
324  #ifdef reg_CODE  
325      /*      known_return_p = codeptr->constants[KNOWN_RETURN_P_SLOT] != NIL;
326       * With the known-return convention, we definitely do NOT want to  
327       * mangle the CODE register because it isn't pointing to the bogus      {
328       * LRA but to the actual routine.          lispobj *args = current_control_stack_pointer;
329       */  
330      if (codeptr->constants[KNOWN_RETURN_P_SLOT] == NIL)          /*
331          SC_REG(scp, reg_CODE) = lra;           * Because HANDLE_BREAKPOINT can GC, the LRA could move, and
332             * we need to know where it went so we can return to the
333             * correct place.  We do this by saving the LRA on the Lisp
334             * stack.  If GC moves the LRA, the stack entry will get
335             * updated appropriately too.
336             */
337            current_control_stack_pointer += 1;
338            args[0] = lra;
339    
340            funcall3(SymbolFunction(HANDLE_BREAKPOINT), offset, code, alloc_sap(scp));
341    
342            /*
343             * Breakpoint handling done.  Get the (possibly changed) LRA
344             * value off the stack so we know where to return to.
345             */
346            lra = args[0];
347            current_control_stack_pointer -= 1;
348    
349    #ifdef reg_CODE
350            /*
351             * With the known-return convention, we definitely do NOT want
352             * to mangle the CODE register because it isn't pointing to
353             * the bogus LRA but to the actual routine.
354             */
355            if (!known_return_p) {
356                SC_REG(scp, reg_CODE) = lra;
357            }
358  #endif  #endif
359        }
360    
361      undo_fake_foreign_function_call(scp);      undo_fake_foreign_function_call(scp);
362      return (void *) (lra - type_OtherPointer + sizeof(lispobj));      return (void *) (lra - type_OtherPointer + sizeof(lispobj));
363  }  }

Legend:
Removed from v.1.20  
changed lines
  Added in v.1.20.6.1

  ViewVC Help
Powered by ViewVC 1.1.5