diff --git a/browser/browse.cpp b/browser/browse.cpp index 69f8bfa..c8fbda9 100644 --- a/browser/browse.cpp +++ b/browser/browse.cpp @@ -640,6 +640,11 @@ bool Browser::TraceView::goto_pc(unsigned long long pc, int dir) return goto_physline(target_line); } +bool Browser::TraceView::goto_cpu_exception(int dir) +{ + return goto_pc(CPU_EXCEPTION_PC, dir); +} + struct TraceParseContext : ParseContext { Browser &br; TraceParseContext(Browser &br) : br(br) {} diff --git a/browser/browse.hh b/browser/browse.hh index 3979be9..83c62f2 100644 --- a/browser/browse.hh +++ b/browser/browse.hh @@ -111,6 +111,7 @@ class Browser : public IndexNavigator { bool goto_visline(unsigned line); bool goto_buffer_limit(bool end); bool goto_pc(unsigned long long pc, int dir); + bool goto_cpu_exception(int dir); bool position_hidden(); bool get_current_pc(unsigned long long &pc); diff --git a/browser/curses.cpp b/browser/curses.cpp index 352ccd2..818b37f 100644 --- a/browser/curses.cpp +++ b/browser/curses.cpp @@ -781,6 +781,15 @@ class TraceBuffer : public Window { } } + void goto_cpu_exception(int dir) + { + if (vu.goto_cpu_exception(dir)) { + selected_event = UINT_MAX; + update_scrtop(false, 1, 2); + update_other_windows(); + } + } + void draw(int x, int y, cursorpos *cp) { cp->visible = false; @@ -867,6 +876,7 @@ class TraceBuffer : public Window { {"t", _("Jump to a specified time position")}, {"l", _("Jump to a specified line number of the trace file")}, {"p, P", _("Jump to the next / previous visit to a PC location")}, + {"e, E", _("Jump to the next / previous CPU exception, if any")}, {"", ""}, {"r", _("Toggle display of the core registers")}, {"S, D", _("Toggle display of the single / double FP registers")}, @@ -1080,6 +1090,9 @@ class TraceBuffer : public Window { if (vu.get_current_pc(pc)) goto_pc(pc, c == 'n' ? +1 : -1); return true; + } else if (c == 'e' || c == 'E') { + goto_cpu_exception(c == 'e' ? +1 : -1); + return true; } else if (c == 'r') { // Toggle core register display window on/off set_crdisp(crdisp == NULL); diff --git a/browser/wx.cpp b/browser/wx.cpp index 69d7bff..ed31f73 100644 --- a/browser/wx.cpp +++ b/browser/wx.cpp @@ -1725,6 +1725,7 @@ class TraceWindow : public TextViewWindow { void pcedit_unfocused(wxFocusEvent &event); void reset_pcedit(); template void pc_nextprev(wxCommandEvent &event); + template void exc_nextprev(wxCommandEvent &event); virtual bool keypress(wxKeyEvent &event) override; @@ -1851,6 +1852,8 @@ TraceWindow::TraceWindow(GuiTarmacBrowserApp *app, Browser &br) wxWindowID mi_newneonreg = NewControlId(); wxWindowID mi_newmvereg = NewControlId(); wxWindowID mi_recentre = NewControlId(); + wxWindowID mi_nextexc = NewControlId(); + wxWindowID mi_prevexc = NewControlId(); mi_calldepth = NewControlId(); mi_highlight = NewControlId(); mi_branchtarget = wxID_NONE; @@ -1875,6 +1878,12 @@ TraceWindow::TraceWindow(GuiTarmacBrowserApp *app, Browser &br) newmenu->Append(mi_newmvereg, _("MVE vector reg view")); filemenu->InsertSeparator(pos++); + newmenu = new wxMenu; + editmenu->AppendSeparator(); + editmenu->Append(wxID_ANY, _("Find CPU exception..."), newmenu); + newmenu->Append(mi_nextexc, _("Next")); + newmenu->Append(mi_prevexc, _("Previous")); + wxMenu *viewmenu = new wxMenu; menubar->Append(viewmenu, _("&View")); { @@ -1903,6 +1912,8 @@ TraceWindow::TraceWindow(GuiTarmacBrowserApp *app, Browser &br) if (mi_branchtarget != wxID_NONE) Bind(wxEVT_MENU, &TraceWindow::branchtarget_menuaction, this, mi_branchtarget); + Bind(wxEVT_MENU, &TraceWindow::exc_nextprev<+1>, this, mi_nextexc); + Bind(wxEVT_MENU, &TraceWindow::exc_nextprev<-1>, this, mi_prevexc); menubar->Check(mi_calldepth, depth_indentation); menubar->Check(mi_highlight, syntax_highlight); @@ -2612,6 +2623,15 @@ template void TraceWindow::pc_nextprev(wxCommandEvent &event) drawing_area->Refresh(); } +template void TraceWindow::exc_nextprev(wxCommandEvent &event) +{ + if (vu.goto_cpu_exception(direction)) { + update_location(UpdateLocationType::NewVis); + keep_visnode_in_view(); + } + drawing_area->Refresh(); +} + bool TraceWindow::keypress(wxKeyEvent &event) { switch (event.GetKeyCode()) { diff --git a/lib/index.cpp b/lib/index.cpp index 4e28cf9..3930ae1 100644 --- a/lib/index.cpp +++ b/lib/index.cpp @@ -108,6 +108,7 @@ class Index : ParseReceiver { AVLDisk *seqtree; Time current_time; bool seen_instruction_at_current_time; + bool seen_cpu_exception_at_current_line; set pending_calls; set found_callrets; bool aarch64_used; @@ -444,10 +445,13 @@ void Index::got_event(ExceptionEvent &ev) { got_event_common(&ev, false); - ByPCPayload bypcp; - bypcp.trace_file_firstline = prev_lineno; - bypcp.pc = CPU_EXCEPTION_PC; - bypcroot = bypctree->insert(bypcroot, bypcp); + if (!seen_cpu_exception_at_current_line) { + ByPCPayload bypcp; + bypcp.trace_file_firstline = prev_lineno; + bypcp.pc = CPU_EXCEPTION_PC; + bypcroot = bypctree->insert(bypcroot, bypcp); + seen_cpu_exception_at_current_line = true; + } } void Index::delete_from_memtree(char type, Addr addr, size_t size) @@ -922,6 +926,7 @@ void Index::got_event_common(TarmacEvent *event, bool is_instruction) prev_lineno = lineno; seen_any_event = true; + seen_cpu_exception_at_current_line = false; } if (is_instruction) @@ -982,6 +987,7 @@ void Index::open_trace_file() last_memroot = memroot; current_time = -(Time)1; seen_instruction_at_current_time = false; + seen_cpu_exception_at_current_line = false; bypcroot = 0; true_lineno = 0; lineno = 1;