Subject: Re: kern/10016: ddb can get stuck in infinite uvm_fault()ing
To: None <gnats-bugs@gnats.netbsd.org>
From: John Hawkinson <jhawk@mit.edu>
List: netbsd-bugs
Date: 05/04/2000 18:05:37
| uvm_fault() is faulting inside db_read_bytes(), because the
| code segment is invalid:
| 
| _db_read_bytes+0x10:    movb    0(%ecx),%al
| db> t
| _db_read_bytes(0,4,c0548cf8,c04dab64,c0548d38) at _db_read_bytes+0x10
| _db_get_value(0,4,0,5,0) at _db_get_value+0x18
| _db_stop_at_pc(c04dab64,c0548d38) at _db_stop_at_pc+0x1c2
| _db_trap(5,0,1,ffffffff,c0548e30) at _db_trap+0x39
| _kdb_trap(5,0,c0548dac) at _kdb_trap+0xb4
| _trap() at _trap+0x168
| --- trap (number 5) ---
| (null)(ff2) at 0
| _pnpbios_getnode(1,c0548e30,c06b9600,d2) at _pnpbios_getnode+0x6a

This occurs on single-stepping (or until-ing) into pnpbioscall() and
off into biosland.

It seems that db_stop_at_pc() decides that the PC (eip) is zero, and
calls db_get_value(pc,...) [db_run.c]:

   173          if (db_run_mode == STEP_CALLT) {
   174              db_expr_t ins = db_get_value(pc, sizeof(int), FALSE);
   175  
   176              /* continue until call or return */
   177  
   178              if (!inst_call(ins) &&
   179                  !inst_return(ins) &&
   180                  !inst_trap_return(ins)) {
   181                  return (FALSE); /* continue */
   182              }
   183          }

pc is initialized from the passed in registers:

    83          pc = PC_REGS(regs);

which presumbly written by the trap handler.

I don't know what to do. db_stop_at_pc() can be made to return in the pc==0
case and that's fine, but db_restart_at_pc() doesn't seem to be quite
so simple, so I'm not sure what to do with that case.

On some level, one expects this stuff to break if you start single-stepping
into the bios, but it would be nice if it were a bit more robust.

I guess it's a bug in the trap handler that is writing the pc?

--jhawk