Raymond Toy pushed to branch issue-97-define-ud2-inst at cmucl / cmucl

Commits:

4 changed files:

Changes:

  • src/code/debug-int.lisp
    ... ... @@ -4477,9 +4477,6 @@ The result is a symbol or nil if the routine cannot be found."
    4477 4477
     ;;;
    
    4478 4478
     (defun handle-breakpoint (offset component signal-context)
    
    4479 4479
       (let ((data (breakpoint-data component offset nil)))
    
    4480
    -    (format t "(handle-breakpoint ~A ~A ~A)~%"
    
    4481
    -	    offset component signal-context)
    
    4482
    -    (format t "  data = ~A~%" data)
    
    4483 4480
         (unless data
    
    4484 4481
           (error (intl:gettext "Unknown breakpoint in ~S at offset ~S.")
    
    4485 4482
     	      (debug-function-name (debug-function-from-pc component offset))
    

  • src/lisp/breakpoint.c
    ... ... @@ -192,8 +192,6 @@ compute_offset(os_context_t * scp, lispobj code, boolean function_end)
    192 192
     static int
    
    193 193
     compute_offset(os_context_t * scp, lispobj code, boolean function_end)
    
    194 194
     {
    
    195
    -    extern unsigned int debug_handlers;
    
    196
    -    
    
    197 195
         DPRINTF(debug_handlers, (stderr, "compute_offset: code = 0x%lx\n", code));
    
    198 196
         
    
    199 197
         if (code == NIL)
    
    ... ... @@ -257,8 +255,6 @@ handle_breakpoint(int signal, int subcode, os_context_t * scp)
    257 255
     void
    
    258 256
     handle_breakpoint(int signal, int subcode, os_context_t * scp)
    
    259 257
     {
    
    260
    -    extern unsigned int debug_handlers;
    
    261
    -
    
    262 258
         lispobj code, scp_sap = alloc_sap(scp);
    
    263 259
     
    
    264 260
         fake_foreign_function_call(scp);
    

  • src/lisp/x86-arch.c
    ... ... @@ -153,7 +153,8 @@ arch_skip_instruction(os_context_t * context)
    153 153
         /* Get and skip the lisp error code. */
    
    154 154
         char* pc = (char *) SC_PC(context);
    
    155 155
         
    
    156
    -    pc += 2;        /* skip 0x0f and 0x0b */
    
    156
    +    /* Skip over the UD2 inst (0x0f, 0x0b) */
    
    157
    +    pc += 2;
    
    157 158
     
    
    158 159
         code = *pc++;
    
    159 160
         SC_PC(context) = (unsigned long) pc;
    
    ... ... @@ -173,6 +174,8 @@ arch_skip_instruction(os_context_t * context)
    173 174
     	  break;
    
    174 175
     
    
    175 176
           case trap_Breakpoint:
    
    177
    +          lose("Unexpected breakpoint trap in arch_skip_instruction\n");
    
    178
    +          break;
    
    176 179
           case trap_FunctionEndBreakpoint:
    
    177 180
     	  break;
    
    178 181
     
    
    ... ... @@ -231,6 +234,11 @@ arch_remove_breakpoint(void *pc, unsigned long orig_inst)
    231 234
                 (stderr, "arch_remove_breakpoint: %p orig %lx\n",
    
    232 235
                  pc, orig_inst));
    
    233 236
         unsigned char *ptr = (unsigned char *) pc;
    
    237
    +    /*
    
    238
    +     * Just restore all the bytes from orig_inst.  Should we just
    
    239
    +     * re-install just the one byte that was taken by the int3
    
    240
    +     * instruction?
    
    241
    +     */
    
    234 242
         ptr[0] = orig_inst & 0xff;
    
    235 243
         ptr[1] = (orig_inst >> 8) & 0xff;
    
    236 244
         ptr[2] = (orig_inst >> 16) & 0xff;
    
    ... ... @@ -267,8 +275,12 @@ arch_do_displaced_inst(os_context_t * context, unsigned long orig_inst)
    267 275
     
    
    268 276
         *((char *) pc) = orig_inst & 0xff;
    
    269 277
     
    
    278
    +    /*
    
    279
    +     * If we have the SC_EFLAGS macro, we can enable single-stepping
    
    280
    +     * by setting the bit.  Otherwise, we need a more complicated way
    
    281
    +     * of enabling single-stepping.
    
    282
    +     */
    
    270 283
     #ifdef SC_EFLAGS
    
    271
    -    /* Enable single-stepping */
    
    272 284
         SC_EFLAGS(context) |= 0x100;
    
    273 285
     #else
    
    274 286
     
    
    ... ... @@ -305,6 +317,11 @@ arch_do_displaced_inst(os_context_t * context, unsigned long orig_inst)
    305 317
     }
    
    306 318
     
    
    307 319
     
    
    320
    +/*
    
    321
    + * Handles the break instruction from lisp, which is now UD2 followed
    
    322
    + * by the trap code.  In particular, this does not handle the
    
    323
    + * breakpoint traps.
    
    324
    + */
    
    308 325
     void
    
    309 326
     sigill_handler(HANDLER_ARGS)
    
    310 327
     {
    
    ... ... @@ -322,9 +339,6 @@ sigill_handler(HANDLER_ARGS)
    322 339
                  *((unsigned char*)SC_PC(context) + 3),
    
    323 340
                  *((unsigned char*)SC_PC(context) + 4)));
    
    324 341
     
    
    325
    -    if (single_stepping) {
    
    326
    -        lose("sigill handler with single-stepping enabled?\n");
    
    327
    -    }
    
    328 342
         
    
    329 343
         /* This is just for info in case monitor wants to print an approx */
    
    330 344
         current_control_stack_pointer = (unsigned long *) SC_SP(os_context);
    
    ... ... @@ -346,6 +360,14 @@ sigill_handler(HANDLER_ARGS)
    346 360
         DPRINTF(debug_handlers,
    
    347 361
                 (stderr, "pc %x\n",  *(unsigned short *)SC_PC(context)));
    
    348 362
     
    
    363
    +    /*
    
    364
    +     * Make sure the trapping instruction is UD2.  Abort if not.
    
    365
    +     *
    
    366
    +     * TODO: aborting is probably not the best idea.  Could get here
    
    367
    +     * from other illegal instructions in, say, C code?  Maybe we
    
    368
    +     * should call interrupt_handle_now, as we do below for an unknown
    
    369
    +     * trap code?
    
    370
    +     */
    
    349 371
         if (*(unsigned short *) SC_PC(context) == 0x0b0f) {
    
    350 372
             trap = *(((char *)SC_PC(context)) + 2);
    
    351 373
         } else {
    
    ... ... @@ -413,6 +435,9 @@ sigill_handler(HANDLER_ARGS)
    413 435
         }
    
    414 436
     }
    
    415 437
     
    
    438
    +/*
    
    439
    + * Handles the breakpoint trap (int3) and also single-stepping
    
    440
    + */
    
    416 441
     void
    
    417 442
     sigtrap_handler(HANDLER_ARGS) 
    
    418 443
     {
    
    ... ... @@ -464,6 +489,13 @@ sigtrap_handler(HANDLER_ARGS)
    464 489
     
    
    465 490
         DPRINTF(debug_handlers, (stderr, "*C break\n"));
    
    466 491
     
    
    492
    +    /*
    
    493
    +     * The int3 instruction causes a trap that leaves us just after
    
    494
    +     * the instruction.  Backup one so we're at the beginning.  This
    
    495
    +     * is really important so that when we handle the breakpoint, the
    
    496
    +     * offset of the instruction matches where Lisp thinks the
    
    497
    +     * breakpoint was placed.
    
    498
    +     */
    
    467 499
         SC_PC(os_context) -= 1;
    
    468 500
     
    
    469 501
         handle_breakpoint(signal, CODE(code), os_context);
    

  • src/lisp/x86-arch.h
    ... ... @@ -9,6 +9,13 @@
    9 9
     extern int arch_support_sse2(void);
    
    10 10
     extern boolean os_support_sse2(void);
    
    11 11
     
    
    12
    +/*
    
    13
    + * Set to non-zero to enable debug prints for debugging the sigill and
    
    14
    + * sigtrap handlers and for debugging breakpoints.
    
    15
    + */
    
    16
    +extern unsigned int debug_handlers;
    
    17
    +
    
    18
    +
    
    12 19
     /*
    
    13 20
      * Define macro to allocate a local array of the appropriate size
    
    14 21
      * where the fpu state can be stored.