diff --git a/gdbgui/src/js/Breakpoints.jsx b/gdbgui/src/js/Breakpoints.jsx index 4e67e911..6b189343 100644 --- a/gdbgui/src/js/Breakpoints.jsx +++ b/gdbgui/src/js/Breakpoints.jsx @@ -5,6 +5,7 @@ import Actions from "./Actions.js"; import Util from "./Util.js"; import FileOps from "./FileOps.jsx"; import { FileLink } from "./Links"; +import constants from "./constants.js"; const BreakpointSourceLineCache = { _cache: {}, @@ -26,6 +27,13 @@ const BreakpointSourceLineCache = { }; class Breakpoint extends React.Component { + constructor(props) { + super(props); + this.state = { + breakpoint_condition: "", + editing_breakpoint_condition: false + }; + } get_source_line(fullname, linenum) { // if we have the source file cached, we can display the line of text const MAX_CHARS_TO_SHOW_FROM_SOURCE = 40; @@ -78,6 +86,23 @@ class Breakpoint extends React.Component { return `${bkpt.times} hits`; } } + on_change_bkpt_cond(e) { + this.setState({ + breakpoint_condition: e.target.value, + editing_breakpoint_condition: true + }); + } + on_key_up_bktp_cond(number, e) { + if (e.keyCode === constants.ENTER_BUTTON_NUM) { + this.setState({ editing_breakpoint_condition: false }); + Breakpoints.set_breakpoint_condition(e.target.value, number); + } + } + on_break_cond_click(e) { + this.setState({ + editing_breakpoint_condition: true + }); + } render() { let b = this.props.bkpt, checked = b.enabled === "y" ? "checked" : "", @@ -122,6 +147,39 @@ class Breakpoint extends React.Component { ); } else { let func = b.func === undefined ? "(unknown function)" : b.func; + let break_condition = ( +
+ + + condition + +
+ ); + if (this.state.editing_breakpoint_condition) { + break_condition = ( + + ); + } const times_hit = this.get_num_times_hit(b); function_jsx = ( @@ -129,10 +187,23 @@ class Breakpoint extends React.Component { {info_glyph} {func} - + thread groups: {b["thread-groups"]} - + {break_condition} + {times_hit} @@ -203,6 +274,12 @@ class Breakpoints extends React.Component { GdbApi.run_gdb_command([`-break-enable ${bkpt_num}`, GdbApi.get_break_list_cmd()]); } } + static set_breakpoint_condition(condition, bkpt_num) { + GdbApi.run_gdb_command([ + `-break-condition ${bkpt_num} ${condition}`, + GdbApi.get_break_list_cmd() + ]); + } static remove_breakpoint_if_present(fullname, line) { if (Breakpoints.has_breakpoint(fullname, line)) { let number = Breakpoints.get_breakpoint_number(fullname, line); @@ -256,6 +333,12 @@ class Breakpoints extends React.Component { .filter(b => b.fullname_to_display === fullname && b.enabled !== "y") .map(b => parseInt(b.line)); } + static get_conditional_breakpoint_lines_for_file(fullname) { + return store + .get("breakpoints") + .filter(b => b.fullname_to_display === fullname && b.cond !== undefined) + .map(b => parseInt(b.line)); + } static save_breakpoints(payload) { store.set("breakpoints", []); if (payload && payload.BreakpointTable && payload.BreakpointTable.body) { diff --git a/gdbgui/src/js/SourceCode.jsx b/gdbgui/src/js/SourceCode.jsx index 4204eb6e..74dd5335 100644 --- a/gdbgui/src/js/SourceCode.jsx +++ b/gdbgui/src/js/SourceCode.jsx @@ -159,6 +159,7 @@ class SourceCode extends React.Component { line_num_being_rendered, has_bkpt, has_disabled_bkpt, + has_conditional_bkpt, assembly_for_line, paused_addr ) { @@ -188,10 +189,12 @@ class SourceCode extends React.Component { } let gutter_cls = ""; - if (has_bkpt) { - gutter_cls = "breakpoint"; - } else if (has_disabled_bkpt) { + if (has_disabled_bkpt) { gutter_cls = "disabled_breakpoint"; + } else if (has_conditional_bkpt) { + gutter_cls = "conditional_breakpoint"; + } else if (has_bkpt) { + gutter_cls = "breakpoint"; } let assembly_content = []; @@ -359,6 +362,9 @@ class SourceCode extends React.Component { disabled_breakpoint_lines = Breakpoints.get_disabled_breakpoint_lines_for_file( this.state.fullname_to_render ), + conditional_breakpoint_lines = Breakpoints.get_conditional_breakpoint_lines_for_file( + this.state.fullname_to_render + ), line_gdb_is_paused_on = this.state.paused_on_frame ? parseInt(this.state.paused_on_frame.line) : 0; @@ -380,6 +386,8 @@ class SourceCode extends React.Component { let has_bkpt = bkpt_lines.indexOf(line_num_being_rendered) !== -1, has_disabled_bkpt = disabled_breakpoint_lines.indexOf(line_num_being_rendered) !== -1, + has_conditional_bkpt = + conditional_breakpoint_lines.indexOf(line_num_being_rendered) !== -1, is_gdb_paused_on_this_line = this.is_gdb_paused_on_this_line( line_num_being_rendered, line_gdb_is_paused_on @@ -394,6 +402,7 @@ class SourceCode extends React.Component { line_num_being_rendered, has_bkpt, has_disabled_bkpt, + has_conditional_bkpt, assembly_for_line, paused_addr ) diff --git a/gdbgui/static/css/gdbgui.css b/gdbgui/static/css/gdbgui.css index 0c462fc2..cc658f3a 100644 --- a/gdbgui/static/css/gdbgui.css +++ b/gdbgui/static/css/gdbgui.css @@ -29,6 +29,9 @@ td{ .bold{ font-weight: bold; } +.italic{ + font-style: italic; +} .pre{ white-space: pre; } @@ -170,6 +173,10 @@ div.breakpoint:hover div.breakpoint_trashcan, .line_num.disabled_breakpoint{ background: #ffd6d7 !important; } +.line_num.conditional_breakpoint{ + background: #ff9966 !important; + color:black; +} td.assembly{ padding-bottom: 0px; padding-top: 0px;