OSDN Git Service

[VM][I386_NP21][DEBUGGER] Add call trace feature.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 27 May 2020 10:50:32 +0000 (19:50 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 27 May 2020 10:50:32 +0000 (19:50 +0900)
source/src/debugger.cpp
source/src/vm/common_vm/CMakeLists.txt
source/src/vm/debugger.h
source/src/vm/device.h
source/src/vm/i386_np21.cpp
source/src/vm/i386_np21.h
source/src/vm/libcpu_newdev/device.cpp
source/src/vm/libcpu_newdev/device.h
source/src/vm/np21/i386c/ia32/cpu.cpp
source/src/vm/np21/i386c/ia32/groups.cpp
source/src/vm/np21/i386c/ia32/instructions/ctrl_trans.cpp

index 85606aa..1046da5 100644 (file)
@@ -806,27 +806,21 @@ void* debugger_thread(void *lpx)
                                                strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", timedat);
                                                log_fio.Fprintf("**** Start of logging CALL TRACE %d steps for %s at %s.%06ld ****\n\n", steps, target->this_device_name, timestr, tv.tv_usec);
                                        }
-                                       int begin_step = (target_debugger->cpu_trace_ptr - steps) & (MAX_CPU_TRACE - 1);
-                                       int max_step = target_debugger->cpu_trace_ptr & (MAX_CPU_TRACE - 1);
+                                       int begin_step = (target_debugger->cpu_trace_call_ptr - steps) & (MAX_CPU_TRACE - 1);
+                                       int max_step = target_debugger->cpu_trace_call_ptr & (MAX_CPU_TRACE - 1);
                                        int steps_left = steps;
-                                       if(!(target_debugger->cpu_trace_overwrap)) {
-                                               if(steps_left > max_step) {
-                                                       begin_step = 0;
-                                                       steps_left = max_step;
-                                                       steps = max_step;
-                                               }
-                                       }
                                        for(int i = begin_step; i != max_step; i = ((i + 1) & (MAX_CPU_TRACE - 1)) ) {
                                                int index = i;
 
                                                if(!(target_debugger->cpu_trace[index] & ~target->get_debug_prog_addr_mask())) {
                                                        int len = 0;
                                                        bool hit = target->debug_rewind_call_trace(
-                                                               target_debugger->cpu_trace[index] & target->get_debug_prog_addr_mask(),
+                                                               target_debugger->cpu_trace_call[i] & target->get_debug_prog_addr_mask(),
                                                                len,
                                                                buffer,
                                                                array_length(buffer),
-                                                               target_debugger->cpu_trace_userdata[index]);
+                                                               target_debugger->cpu_trace_call_type[i]
+                                                               );
                                                        if(hit) {
                                                                const _TCHAR *name = my_get_symbol(target, target_debugger->cpu_trace[index] & target->get_debug_prog_addr_mask());
                                                                if(name != NULL) {
index 3fce0ba..4dff796 100644 (file)
@@ -1,6 +1,6 @@
 message("* vm/common_vm")
 
-SET(THIS_LIB_VERSION 2.26.1)
+SET(THIS_LIB_VERSION 2.26.2)
 
 #include(cotire)
 set(s_vm_common_vm_srcs
index bf9ac85..0afa265 100644 (file)
@@ -21,8 +21,7 @@
 #define MAX_COMMAND_HISTORY    32
 //#define MAX_CPU_TRACE                0x01000000 /* 16Msteps */
 #define MAX_CPU_TRACE          0x00100000 /* 1Msteps */
-
-
+#define TRACE_TYPE_CALL                0x00000000
 typedef struct {
        struct {
                uint32_t addr, mask;
@@ -100,10 +99,13 @@ public:
                memset(cpu_trace_exp, 0x00, sizeof(cpu_trace_exp));
                memset(cpu_trace_exp_map, 0x00, sizeof(cpu_trace_exp_map));
                memset(cpu_trace_userdata, 0x00, sizeof(cpu_trace_userdata));
+               memset(cpu_trace_call_type, 0x00, sizeof(cpu_trace_call_type));
+               memset(cpu_trace_call, 0x00, sizeof(cpu_trace_call));
                exception_happened = false;
                stop_on_exception = true;
                prev_cpu_trace = 0xffffffff;
                cpu_trace_ptr = 0;
+               cpu_trace_call_ptr = 0;
                cpu_trace_overwrap = false;
                set_device_name(_T("Debugger"));
        }
@@ -499,17 +501,39 @@ public:
                }
                first_symbol = last_symbol = NULL;
        }
-       void add_cpu_trace_exception(uint64_t exception_code)
+       void __FASTCALL add_cpu_trace_exception(uint64_t exception_code)
        {
                cpu_trace_exp[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] = exception_code; 
                cpu_trace_exp_map[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] = true; 
        }
        // Userdata should after executing instruction.
-       void add_cpu_trace_userdata(uint32_t data, uint32_t mask)
+       void __FASTCALL add_cpu_trace_userdata(uint32_t data, uint32_t mask)
        {
                cpu_trace_userdata[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] &= ~mask;
                cpu_trace_userdata[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] |= (data & mask);
        }
+       void __FASTCALL add_cpu_trace_irq(uint32_t pc, uint32_t irq)
+       {
+               cpu_trace_call[cpu_trace_call_ptr] = pc;
+               cpu_trace_call_type[cpu_trace_call_ptr] = ((uint64_t)irq << 32);
+               cpu_trace_call_ptr++;
+               cpu_trace_call_ptr &= (MAX_CPU_TRACE - 1);
+       }
+       void __FASTCALL add_cpu_trace_call(uint32_t pc, uint32_t target)
+       {
+               cpu_trace_call[cpu_trace_call_ptr] = pc;
+               cpu_trace_call_type[cpu_trace_call_ptr] = (uint64_t)target;
+               cpu_trace_call_ptr++;
+               cpu_trace_call_ptr &= (MAX_CPU_TRACE - 1);
+       }
+       void __FASTCALL add_cpu_trace_return(uint32_t pc)
+       {
+               cpu_trace_call[cpu_trace_call_ptr] = pc;
+               cpu_trace_call_type[cpu_trace_call_ptr] = (uint64_t)0x80000000 << 32;
+               cpu_trace_call_ptr++;
+               cpu_trace_call_ptr &= (MAX_CPU_TRACE - 1);
+       }
+       
        void add_cpu_trace(uint32_t pc)
        {
                if(prev_cpu_trace != pc) {
@@ -536,9 +560,12 @@ public:
        uint32_t cpu_trace[MAX_CPU_TRACE], prev_cpu_trace;
        uint64_t cpu_trace_exp[MAX_CPU_TRACE];
        uint32_t cpu_trace_userdata[MAX_CPU_TRACE]; // ToDo: Is need larger userdata?
+       uint32_t cpu_trace_call[MAX_CPU_TRACE]; // ToDo: Is need larger userdata?
+       uint64_t cpu_trace_call_type[MAX_CPU_TRACE]; // ToDo: Is need larger userdata?
        
        bool cpu_trace_exp_map[MAX_CPU_TRACE];
        int cpu_trace_ptr;
+       int cpu_trace_call_ptr;
        bool cpu_trace_overwrap;
 };
 
index 7d623c6..5e5ae5f 100644 (file)
@@ -1234,7 +1234,7 @@ public:
        {
                return 0;
        }
-       virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint32_t userdata = 0)
+       virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0)
        {
                size = 0;
                return false;
index ac266e5..8a78daa 100644 (file)
@@ -315,9 +315,16 @@ int I386::run_one_opecode()
                CPU_EXEC();
                if(nmi_pending) {
                        CPU_INTERRUPT(2, 0);
+                       if(device_debugger != NULL) {
+                               device_debugger->add_cpu_trace_irq(get_pc(), 2);
+                       }
                        nmi_pending = false;
                } else if(irq_pending && CPU_isEI) {
-                       CPU_INTERRUPT(device_pic->get_intr_ack(), 0);
+                       uint32_t intr_level = device_pic->get_intr_ack();
+                       CPU_INTERRUPT(intr_level, 0);
+                       if(device_debugger != NULL) {
+                               device_debugger->add_cpu_trace_irq(get_pc(), intr_level);
+                       }
                        irq_pending = false;
                        device_pic->update_intr();
                }
@@ -336,9 +343,16 @@ int I386::run_one_opecode()
                CPU_EXEC();
                if(nmi_pending) {
                        CPU_INTERRUPT(2, 0);
+                       if(device_debugger != NULL) {
+                               device_debugger->add_cpu_trace_irq(get_pc(), 2);
+                       }
                        nmi_pending = false;
                } else if(irq_pending && CPU_isEI) {
-                       CPU_INTERRUPT(device_pic->get_intr_ack(), 0);
+                       uint32_t intr_level = device_pic->get_intr_ack();
+                       CPU_INTERRUPT(intr_level, 0);
+                       if(device_debugger != NULL) {
+                               device_debugger->add_cpu_trace_irq(get_pc(), intr_level);
+                       }
                        irq_pending = false;
                        device_pic->update_intr();
                }
@@ -717,37 +731,25 @@ bool I386::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
        return true;
 }
 
-bool I386::debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint32_t userdata)
+bool I386::debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata)
 {
        size = 0;
        _TCHAR prefix[128] = {0};
-       if((userdata & 0x8000fff0) != 0) { // Maybe call/ret/jmp/intr
-               if(userdata & I386_TRACE_DATA_BIT_IRQ) {
-                       strncpy(prefix, _T("*IRQ HAPPENED*"), 127);
-               } else if(userdata & I386_TRACE_DATA_BIT_EXCEPTION) {
-                       strncpy(prefix,  _T("*EXCEPTION HAPPENED*"), 127);
-               } else if(userdata & I386_TRACE_DATA_BIT_INT) {
-                       strncpy(prefix, _T("*INTXX*"), 127);
-               } else if(userdata & I386_TRACE_DATA_BIT_RET) {
-                       strncpy(prefix, _T("*RETURN*"), 127);
-               } else if(userdata & I386_TRACE_DATA_BIT_JMP) {
-                       strncpy(prefix, _T("*JMP*"), 127);
-               } else if(userdata & I386_TRACE_DATA_BIT_CALL) {
-                       strncpy(prefix, _T("*CALL*"), 127);
-               } else {
-                       // Not meanful
-                       return false;
-               }
-               _TCHAR dasmbuf[1024] = {0};
-               size = debug_dasm_with_userdata(pc, dasmbuf, 1023, userdata);
-               if(size <= 0) {
-                       strncpy(dasmbuf, 1023, _T("**UNDEFINED BEHAVIOR**"));
-               }
-               my_stprintf_s(buffer, buffer_len, _T("HIT %s    @%08X   %s\n"),
-                                         prefix, pc,  dasmbuf);
-               return true;
+       if((userdata & ((uint64_t)0xffffffff << 32)) == ((uint64_t)0x80000000 << 32)) {
+               my_stprintf_s(prefix, 127, _T("*RETURN*"));
+       } else if((userdata & (uint64_t)0xffffffff00000000) != 0) {
+               my_stprintf_s(prefix, 127, _T("*IRQ %X HAPPENED*"), (uint32_t)(userdata >> 32));
+       }  else {
+               my_stprintf_s(prefix, 127, _T("*CALL TO %08X*"), (uint32_t)userdata);
+       }               
+       _TCHAR dasmbuf[1024] = {0};
+       size = debug_dasm_with_userdata(pc, dasmbuf, 1023, userdata);
+       if(size <= 0) {
+               strncpy(dasmbuf, 1023, _T("**UNDEFINED BEHAVIOR**"));
        }
-       return false;
+       my_stprintf_s(buffer, buffer_len, _T("HIT %s    @%08X   %s\n"),
+                                 prefix, pc,  dasmbuf);
+       return true;
 }
 int I386::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata)
 {
index a35f268..86c1816 100644 (file)
@@ -145,7 +145,7 @@ public:
        virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len);
        virtual bool get_debug_regs_description(_TCHAR *buffer, size_t buffer_len);
        int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0);
-       virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint32_t userdata = 0);
+       virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0);
 //#endif
        bool process_state(FILEIO* state_fio, bool loading);
        
index 9dcd2d3..e6d2e13 100644 (file)
@@ -559,7 +559,7 @@ int DEVICE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_
 {
        return 0;
 }
-bool DEVICE::debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint32_t userdata = 0)
+bool DEVICE::debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0)
 {
                size = 0;
                return false;
index 755534b..aab8a39 100644 (file)
@@ -761,7 +761,7 @@ public:
        virtual bool get_debug_regs_description(_TCHAR *buffer, size_t buffer_len);
        virtual int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len);
        virtual int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0);
-       virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint32_t userdata = 0);
+       virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0);
 /*
        These functions are used for debugging non-cpu device
        Insert debugger between standard read/write functions and these functions for checking breakpoints
index c5213b0..086be89 100644 (file)
@@ -157,6 +157,8 @@ exec_1step(void)
        }
        ctx[ctx_index].opbytes = 0;
 #endif
+       UINT32 old_eip = CPU_PREV_EIP;
+       UINT32 old_addr = 0;
        
        for (prefix = 0; prefix < MAX_PREFIX; prefix++) {
                check_exception(is_debugging);
@@ -181,31 +183,46 @@ exec_1step(void)
                } else {
                        switch(op) {
                        case 0x9a: //CAll
+                               {
+                                       descriptor_t *sdp = &CPU_CS_DESC;
+                                       old_addr = sdp->u.seg.segbase + old_eip;
+                               }
                                op_size |= I386_TRACE_DATA_BIT_CALL;
                                break;
                        case 0xc2: // RET far
                        case 0xc3:
+                               {
+                                       descriptor_t *sdp = &CPU_CS_DESC;
+                                       old_addr = sdp->u.seg.segbase + old_eip;
+                               }
                                op_size |= I386_TRACE_DATA_BIT_RET;
                                break;
                        case 0xca: // RET far
                        case 0xcb:
+                               {
+                                       descriptor_t *sdp = &CPU_CS_DESC;
+                                       old_addr = sdp->u.seg.segbase + old_eip;
+                               }
                                op_size |= I386_TRACE_DATA_BIT_RET;
                                break;
-                       case 0xcc: // INTr
-                       case 0xcd:
-                       case 0xce:
-                               op_size |= I386_TRACE_DATA_BIT_INT;
-                               break;
                        case 0xcf:
+                               {
+                                       descriptor_t *sdp = &CPU_CS_DESC;
+                                       old_addr = sdp->u.seg.segbase + old_eip;
+                               }
                                op_size |= I386_TRACE_DATA_BIT_IRET;
                                break;
                        case 0xe8: //CAll
+                               {
+                                       descriptor_t *sdp = &CPU_CS_DESC;
+                                       old_addr = sdp->u.seg.segbase + old_eip;
+                               }
                                op_size |= I386_TRACE_DATA_BIT_CALL;
                        break;
                        case 0xe9: //JMP
                        case 0xea: //JMP16
                        case 0xeb: //JMP
-                               op_size |= I386_TRACE_DATA_BIT_CALL;
+                               op_size |= I386_TRACE_DATA_BIT_JMP;
                                break;
                        case 0xe3:
                                op_size |= I386_TRACE_DATA_BIT_JMP_COND;
@@ -220,6 +237,26 @@ exec_1step(void)
                /* prefix */
                if (insttable_info[op] & INST_PREFIX) {
                        (*insttable_1byte[0][op])();
+                       switch(op) {
+                       case 0x9a: //CAll
+                       case 0xe8: //CAll
+                               {
+                                       descriptor_t *sdp = &CPU_CS_DESC;
+                                       uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP;
+                                       device_debugger->add_cpu_trace_call(old_addr, new_addr);
+                               }
+                               break;
+                       case 0xc2: // RET far
+                       case 0xc3:
+                       case 0xca: // RET far
+                       case 0xcb:
+                       case 0xcf: // iRET
+                               {
+                                       // ToDo: Collect intr num.
+                                       device_debugger->add_cpu_trace_return(old_addr);
+                               }
+                               break;
+                       }
                        continue;
                }
                break;
@@ -245,6 +282,26 @@ exec_1step(void)
                cpu_debug_rep_cont = 0;
 #endif
                (*insttable_1byte[CPU_INST_OP32][op])();
+               switch(op) {
+               case 0x9a: //CAll
+               case 0xe8: //CAll
+                       {
+                               descriptor_t *sdp = &CPU_CS_DESC;
+                               uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP;
+                               device_debugger->add_cpu_trace_call(old_addr, new_addr);
+                       }
+                       break;
+               case 0xc2: // RET far
+               case 0xc3:
+               case 0xca: // RET far
+               case 0xcb:
+               case 0xcf: // iRET
+                       {
+                               // ToDo: Collect intr num.
+                               device_debugger->add_cpu_trace_return(old_addr);
+                       }
+                       break;
+               }
                check_exception(is_debugging);
                return;
        }
@@ -457,6 +514,37 @@ exec_allstep(void)
                        /* prefix */
                        if (insttable_info[op] & INST_PREFIX) {
                                (*insttable_1byte[0][op])();
+                               switch(op) {
+                               case 0x9a: //CAll
+                               case 0xe8: //CAll
+                                       {
+                                               descriptor_t *sdp = &CPU_CS_DESC;
+                                               uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP;
+                                               device_debugger->add_cpu_trace_call(old_addr, new_addr);
+                                       }
+                                       break;
+                               case 0xcc: // INTr
+                               case 0xcd:
+                               case 0xce:
+                               case 0xf1:
+                                       {
+                                               // ToDo: Collect intr num.
+                                               descriptor_t *sdp = &CPU_CS_DESC;
+                                               uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP;
+                                               device_debugger->add_cpu_trace_call(old_addr, new_addr);
+                                       }
+                                       break;
+                               case 0xc2: // RET far
+                               case 0xc3:
+                               case 0xca: // RET far
+                               case 0xcb:
+                               case 0xcf: // iRET
+                                       {
+                                               // ToDo: Collect intr num.
+                                               device_debugger->add_cpu_trace_return(old_addr);
+                                       }
+                                       break;
+                               }
                                continue;
                        }
                        break;
@@ -482,6 +570,37 @@ exec_allstep(void)
                        cpu_debug_rep_cont = 0;
        #endif
                        (*insttable_1byte[CPU_INST_OP32][op])();
+                       switch(op) {
+                       case 0x9a: //CAll
+                       case 0xe8: //CAll
+                               {
+                                       descriptor_t *sdp = &CPU_CS_DESC;
+                                       uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP;
+                                       device_debugger->add_cpu_trace_call(old_addr, new_addr);
+                               }
+                               break;
+                       case 0xcc: // INTr
+                       case 0xcd:
+                       case 0xce:
+                       case 0xf1:
+                               {
+                                       // ToDo: Collect intr num.
+                                       descriptor_t *sdp = &CPU_CS_DESC;
+                                       uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP;
+                                       device_debugger->add_cpu_trace_call(old_addr, new_addr);
+                               }
+                               break;
+                       case 0xc2: // RET far
+                       case 0xc3:
+                       case 0xca: // RET far
+                       case 0xcb:
+                       case 0xcf: // iRET
+                               {
+                                       // ToDo: Collect intr num.
+                                       device_debugger->add_cpu_trace_return(old_addr);
+                               }
+                               break;
+                       }
                        check_exception(is_debugging);
                        goto cpucontinue; //continue;
                }
index 61f4576..c23f8ec 100644 (file)
@@ -420,8 +420,30 @@ Grp5_Ed(void)
 {
        UINT32 op;
 
+       UINT32 old_eip = CPU_PREV_EIP;
+       UINT32 old_addr = 0;
        GET_PCBYTE(op);
+       UINT32 op_old = op;
+       switch((op >> 3) & 7) {
+       case 2: //CAll
+       case 3: //CAll
+               {
+                       descriptor_t *sdp = &CPU_CS_DESC;
+                       old_addr = sdp->u.seg.segbase + old_eip;
+               }
+               break;
+       }
        (*insttable_G5Ed[(op >> 3) & 7])(op);
+       switch((op >> 3) & 7) {
+       case 2: //CAll
+       case 3: //CAll
+               {
+                       descriptor_t *sdp = &CPU_CS_DESC;
+                       uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP;
+                       device_debugger->add_cpu_trace_call(old_addr, new_addr);
+               }
+               break;
+       }
 }
 
 
index 19890e2..02ddb33 100644 (file)
@@ -1403,6 +1403,14 @@ void
 INT1(void)
 {
 
+       uint32_t old_addr;
+       {
+               descriptor_t *sdp = &CPU_CS_DESC;
+               old_addr = sdp->u.seg.segbase + CPU_PREV_EIP;
+       }
+       if(device_debugger != NULL) {
+               device_debugger->add_cpu_trace_irq(old_addr, 1);
+       }
        CPU_WORKCLOCK(33);
        INTERRUPT(1, INTR_TYPE_SOFTINTR);
 }
@@ -1411,6 +1419,14 @@ INT1(void)
 void
 INT6(void)
 {
+       uint32_t old_addr;
+       {
+               descriptor_t *sdp = &CPU_CS_DESC;
+               old_addr = sdp->u.seg.segbase + CPU_PREV_EIP;
+       }
+       if(device_debugger != NULL) {
+               device_debugger->add_cpu_trace_irq(old_addr, 6);
+       }
        CPU_WORKCLOCK(33);
        INTERRUPT(6, INTR_TYPE_SOFTINTR);
 }
@@ -1435,6 +1451,14 @@ INT3(void)
 #endif
 */
        CPU_WORKCLOCK(33);
+       uint32_t old_addr;
+       {
+               descriptor_t *sdp = &CPU_CS_DESC;
+               old_addr = sdp->u.seg.segbase + CPU_PREV_EIP;
+       }
+       if(device_debugger != NULL) {
+               device_debugger->add_cpu_trace_irq(old_addr, 3);
+       }
        INTERRUPT(3, INTR_TYPE_SOFTINTR);
 }
 
@@ -1447,6 +1471,14 @@ INTO(void)
                return;
        }
        CPU_WORKCLOCK(35);
+       uint32_t old_addr;
+       {
+               descriptor_t *sdp = &CPU_CS_DESC;
+               old_addr = sdp->u.seg.segbase + CPU_PREV_EIP;
+       }
+       if(device_debugger != NULL) {
+               device_debugger->add_cpu_trace_irq(old_addr, 4);
+       }
        INTERRUPT(4, INTR_TYPE_SOFTINTR);
 }
 
@@ -1457,7 +1489,15 @@ INT_Ib(void)
 
        CPU_WORKCLOCK(37);
        if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_IOPL == CPU_IOPL3)) {
+               uint32_t old_addr;
+               {
+                       descriptor_t *sdp = &CPU_CS_DESC;
+                       old_addr = sdp->u.seg.segbase + CPU_PREV_EIP;
+               }
                GET_PCBYTE(vect);
+               if(device_debugger != NULL) {
+                       device_debugger->add_cpu_trace_irq(old_addr, vect);
+               }
 #if defined(ENABLE_TRAP)
                softinttrap(CPU_CS, CPU_EIP - 2, vect);
 #endif