debug.c
来自「具有IDE功能的编辑器」· C语言 代码 · 共 1,371 行 · 第 1/3 页
C
1,371 行
} xdebug_cursor_bookmark_flush (); xdebug_flush_commands (&debug_session); if (!debug_session.progname) if (debug_set_info (0)) return; s = CInputDialog ("debugattach", 0, 0, 0, 30 * FONT_MEAN_WIDTH, TEXTINPUT_LAST_INPUT, _ (" Debug "), _ (" Enter process id to attach to : ")); if (!s) return; p = atol (s); free (s); if (p <= 0) return; debug_session.show_output = 0; if (xdebug_run_program (&debug_session)) return; xdebug_set_break_points (&debug_session); sprintf (t, "attach %ld\n", p); xdebug_append_command (&debug_session, t, ACTION_PROMPT, 0, 0); xdebug_append_command (&debug_session, "info program\n", ACTION_INFO_PROGRAM, 0, 0); xdebug_append_command (&debug_session, "c\n", ACTION_RUNNING, 0, 0);}void debug_detach (unsigned long x){ if (!debug_session.pid) { debug_error1 (&debug_session, _ ("Debugger is not running")); return; } if (debug_session.action) { debug_error1 (&debug_session, _ ("Program is currently running, use Control-C first")); return; } xdebug_append_command (&debug_session, "detach\n", ACTION_QUIT, 0, 0); debug_session.child = 0;}/* resturns 1 on cancel */static int debug_set_info (unsigned long x){ char *inputs[10] = { gettext_noop (""), gettext_noop (""), 0 }; char *input_labels[10] = { gettext_noop ("Program name"), gettext_noop ("Enter program arguments (space for none)"), 0 }; char *check_labels[10] = { gettext_noop ("Show program output"), gettext_noop ("Stop at main() function"), gettext_noop ("Show on stdout"), gettext_noop ("Ignore SIGTTOU"), 0 }; char *check_tool_hints[10] = { gettext_noop ("This will cause the program to be opened udner an rxvt terminal so that its output can be viewed."), gettext_noop ("This will cause the debugger to break at the first\nline of code in the program when issuing a `Start'."), gettext_noop ("This will cause all debugger commands to show at\nthe terminal where you started cooledit."), gettext_noop ("Run `call signal()' inside gdb so that SIGTTOU signals are ignored. Without this gdb sometimes exits."), 0 }; char *input_names[10] = { gettext_noop ("debugprogname"), gettext_noop ("debugargs+"), 0 }; char *input_tool_hint[10] = { gettext_noop ("The executable that you would like to debug - this must be compiled with the -g option"), gettext_noop ("Arguments to be passed to the executable - can be empty"), 0 }; int *checks_values_result[10]; char **inputs_result[10]; int r; inputs_result[0] = &inputs[0]; inputs_result[1] = &inputs[1]; inputs_result[2] = 0; checks_values_result[0] = &debug_session.show_output; checks_values_result[1] = &debug_session.stop_at_main; checks_values_result[2] = &debug_session.show_on_stdout; checks_values_result[3] = &debug_session.ignore_SIGTTOU; checks_values_result[4] = 0; r = CInputsWithOptions (0, 0, 0, _ (" Debug : Program Data "), inputs_result, input_labels, input_names, input_tool_hint, checks_values_result, check_labels, check_tool_hints, INPUTS_WITH_OPTIONS_BROWSE_LOAD_1, 60); if (r) return 1; if (debug_session.progname) free (debug_session.progname); debug_session.progname = inputs[0]; if (debug_session.args) free (debug_session.args); debug_session.args = inputs[1]; if (debug_session.pid) debug_error1 (&debug_session, _ (" The debugger is currently running. You will have \n to kill the debugger for these changes to take effect. ")); return 0;}/* ACTION_STEP is the same as ACTION_RUNNING except that if a user hits it twice in a row, it won't be prone to give "Program is currently running..." messages. */static void debug_step (unsigned long c){ char *cmd; cmd = (char *) c; if (!debug_session.pid) { debug_error1 (&debug_session, _ ("Debugger is not running")); return; } if (debug_session.action) { debug_error1 (&debug_session, _ ("Program is currently running, use Control-C first")); return; } xdebug_append_command (&debug_session, cmd, ACTION_STEP, 0, 0);}static void debug_command (unsigned long c){ char *cmd; cmd = (char *) c; if (!debug_session.pid) { debug_error1 (&debug_session, _ ("Debugger is not running")); return; } if (debug_session.action) { debug_error1 (&debug_session, _ ("Program is currently running, use Control-C first")); return; } xdebug_append_command (&debug_session, cmd, ACTION_RUNNING, 0, 0);}static void debug_show_output (unsigned long c){ char s[MAX_DEBUG_CMD_LEN]; char *cmd; cmd = (char *) c; if (!debug_session.pid) { debug_error1 (&debug_session, _ ("Debugger is not running")); return; } if (debug_session.action) { debug_error1 (&debug_session, _ ("Program is currently running, use Control-C first")); return; } if (!cmd) { cmd = CInputDialog ("debugruncmd", 0, 0, 0, 50 * FONT_MEAN_WIDTH, TEXTINPUT_LAST_INPUT, _ (" Debug "), _ (" Enter debugger command : ")); if (cmd) { sprintf (s, "%s\n", cmd); free (cmd); cmd = s; } } if (!cmd) return; xdebug_append_command (&debug_session, cmd, ACTION_SHOW, 0, 0);}static void debug_break (unsigned long x){ if (!debug_session.pid) { debug_error1 (&debug_session, _ ("Debugger is not running")); return; } if (!debug_session.action) /* already stopped */ return; if (debug_session.action == ACTION_RUNNING || debug_session.action == ACTION_STEP || debug_session.action == ACTION_UNTIL) { xdebug_flush_commands (&debug_session); if (debug_session.child) { kill (debug_session.child, SIGINT); debug_session.action = ACTION_RUNNING; } }}static void debug_finish (unsigned long x){ xdebug_cursor_bookmark_flush (); xdebug_flush_commands (&debug_session); if (debug_session.pool) pool_free (debug_session.pool); debug_session.pool = 0; if (debug_session.pid) { kill (debug_session.pid, SIGTERM); debug_session.pid = 0; CRemoveWatch (debug_session.in, debug_write_callback, WATCH_WRITING); CRemoveWatch (debug_session.out, debug_read_callback, WATCH_READING); close (debug_session.in); close (debug_session.out); if (debug_session.xterm_pid) { kill (debug_session.xterm_pid, SIGTERM); debug_session.xterm_pid = 0; } if (debug_session.child) { kill (debug_session.child, SIGKILL); debug_session.child = 0; } }}static void debug_restart (unsigned long x){ if (debug_session.action) { debug_error1 (&debug_session, _ ("Program is currently running, use Control-C first")); return; } xdebug_cursor_bookmark_flush (); xdebug_flush_commands (&debug_session); if (!debug_session.progname) if (debug_set_info (0)) return; if (!debug_session.pid) { debug_start (); } else { debug_session.child = 0; xdebug_append_command (&debug_session, "k\n", ACTION_PROMPT, 0, 0); xdebug_run (&debug_session); }}static void debug_clear_breakpoints (unsigned long x){ int i; if (debug_session.action) { debug_error1 (&debug_session, _ ("Program is currently running, use Control-C first")); return; } if (debug_session.pid) xdebug_append_command (&debug_session, "d\n", ACTION_PROMPT, 0, 0); for (i = 0; i < last_edit; i++) book_mark_flush (edit[i]->editor, DEBUG_BREAKPOINT_COLOR);}static void debug_conditional (unsigned long x){ if (!debug_session.pid) { debug_error1 (&debug_session, _ ("Debugger is not running")); return; } if (debug_session.action) { debug_error1 (&debug_session, _ ("Program is currently running, use Control-C first")); return; } if (debug_session.condition) free (debug_session.condition); debug_session.condition = CInputDialog ("debugcondition", 0, 0, 0, 50 * FONT_MEAN_WIDTH, TEXTINPUT_LAST_INPUT, _ (" Breakpoint "), _ (" Enter condition on which to break : ")); if (debug_session.condition) xdebug_break_point_special (&debug_session, "b", edit[current_edit]->ident, edit[current_edit]->editor->curs_line + 1, ACTION_CONDITION);}static void debug_break_point (unsigned long x){ char *cmd = "b"; if (debug_session.action) { debug_error1 (&debug_session, _ ("Program is currently running, use Control-C first")); return; } if (book_mark_query_color (edit[current_edit]->editor, edit[current_edit]->editor->curs_line, DEBUG_BREAKPOINT_COLOR)) cmd = "clear"; if (debug_session.pid) xdebug_break_point (&debug_session, cmd, edit[current_edit]->ident, edit[current_edit]->editor->curs_line + 1); else { if (!strcmp (cmd, "clear")) { while (!book_mark_clear (edit[current_edit]->editor, edit[current_edit]->editor->curs_line, DEBUG_BREAKPOINT_COLOR)); edit[current_edit]->editor->force |= REDRAW_COMPLETELY; edit_render_keypress (edit[current_edit]->editor); } else { book_mark_insert (edit[current_edit]->editor, edit[current_edit]->editor->curs_line, DEBUG_BREAKPOINT_COLOR); edit[current_edit]->editor->force |= REDRAW_COMPLETELY; edit_render_keypress (edit[current_edit]->editor); } }}static void debug_add_var (unsigned int x){ char *s; if (!debug_session.pid) { debug_error1 (&debug_session, _ ("Debugger is not running")); return; } if (debug_session.action) { debug_error1 (&debug_session, _ ("Program is currently running, use Control-C first")); return; } s = CInputDialog ("debugvariab", 0, 0, 0, 30 * FONT_MEAN_WIDTH, TEXTINPUT_LAST_INPUT, _ (" Debug "), _ (" Enter variable to display : ")); if (!s) return; if (xdebug_add_variable (&debug_session, s)) { free (s); return; } free (s); xdebug_show_variables (&debug_session);}static void debug_until (unsigned int x){ if (!debug_session.pid) { debug_error1 (&debug_session, _ ("Debugger is not running")); return; } if (debug_session.action) { debug_error1 (&debug_session, _ ("Program is currently running, use Control-C first")); return; } xdebug_break_point (&debug_session, "b", edit[current_edit]->ident, edit[current_edit]->editor->curs_line + 1); xdebug_append_command (&debug_session, "c\n", ACTION_UNTIL, edit[current_edit]->ident, edit[current_edit]->editor->curs_line);}void xdebug_init_animation (void){ CWidget *w; w = CIdent ("menu.debugmenu"); debug_session.r = w->height / 2; debug_session.x = w->width / 2 - debug_session.r; debug_session.y = w->height / 2 - debug_session.r; debug_session.w = w->winid;}void debug_init (void){ memset (&debug_session, 0, sizeof (debug_session)); debug_session.prompt = "(gdb) "; debug_session.get_line = "info line\n"; debug_session.get_source = "info source\n"; debug_session.get_backtrace = "backtrace\n"; debug_session.query[0].query = "( y or n )"; debug_session.query[0].response = "y\n"; debug_session.query[1].query = "(y or n)"; debug_session.query[1].response = "y\n"; debug_session.query[2].query = "<return> to quit---"; debug_session.query[2].response = "\n"; debug_session.query[3].query = 0; debug_session.query[3].response = 0; debug_session.debugger = "cooledit-gdb"; debug_session.stop_at_main = 1; debug_session.ignore_SIGTTOU = 1; xdebug_init_animation ();}void debug_shut (void){ int i; debug_finish (0); CDestroyWidget ("debug_vars.win"); if (debug_session.progname) free (debug_session.progname); if (debug_session.args) free (debug_session.args); if (debug_session.file) free (debug_session.file); if (debug_session.condition) free (debug_session.condition); if (debug_session.break_point_editor) free (debug_session.break_point_editor); for (i = 0; debug_session.variable[i].name && debug_session.variable[i].output; i++) { free (debug_session.variable[i].name); free (debug_session.variable[i].output); } memset (&debug_session, 0, sizeof (debug_session));}void debug_menus (Window parent, Window main_window, int x, int y){ CDrawMenuButton ("menu.debugmenu", parent, main_window, x, y, AUTO_SIZE, 16, _ (" Debug "), _ ("Start\tM-F5"), (int) '~', debug_restart, 0L, _ ("Stop\tC-c"), (int) '~', debug_break, 0L, _ ("Attach"), (int) '~', debug_attach, 0L, _ ("Detach"), (int) '~', debug_detach, 0L, _ ("Toggle breakpoint\tM-F2"), (int) '~', debug_break_point, 0L, _ ("Insert conditional breakpoint"), (int) '~', debug_conditional, 0L, _ ("Clear all breakpoints"), (int) '~', debug_clear_breakpoints, 0L, _ ("Next\tM-F9"), (int) '~', debug_step, (unsigned long) "n\n", _ ("Step\tM-F8"), (int) '~', debug_step, (unsigned long) "s\n", _ ("List back trace"), (int) '~', debug_show_output, (unsigned long) "backtrace\n", _ ("Continue\tM-F4"), (int) '~', debug_command, (unsigned long) "c\n", _ ("Continue until cursor\tM-F3"), (int) '~', debug_until, 0L, _ ("Kill debugger"), (int) '~', debug_finish, 0L, _ ("Enter command...\tM-F1"), (int) '~', debug_show_output, 0L, _ ("Display variable..."), (int) '~', debug_add_var, 0L, _ ("Set info..."), (int) '~', debug_set_info, 0L ); CSetToolHint ("menu.debugmenu", _ ("Interactive graphical debugger"));}/* hack: c is just to check if different keys are pressed - any unique thing can go in there. */static int time_diff (unsigned long c){ static unsigned long c_last = 0; int r = 0; static struct timeval tv = {0, 0}; struct timeval tv_last; tv_last = tv; gettimeofday (&tv, 0); if ((double) ((double) tv.tv_usec / 1000000.0 + (double) tv.tv_sec) - \ ((double) tv_last.tv_usec / 1000000.0 + (double) tv_last.tv_sec) < \ (double) 0.5 && c == c_last) r = 1; c_last = c; return r;}void debug_key_command (int command){ if (time_diff (command)) if (debug_session.action) { return; } if (command == CK_Debug_Stop) { debug_break (0); return; } if (debug_session.n_commands) return; switch (command) { case CK_Debug_Start: debug_restart (0); break; case CK_Debug_Toggle_Break: debug_break_point (0); break; case CK_Debug_Clear: debug_clear_breakpoints (0); break; case CK_Debug_Next: debug_step ((unsigned long) "n\n"); break; case CK_Debug_Step: debug_step ((unsigned long) "s\n"); break; case CK_Debug_Back_Trace: debug_show_output ((unsigned long) "backtrace\n"); break; case CK_Debug_Continue: debug_command ((unsigned long) "c\n"); break; case CK_Debug_Enter_Command: debug_show_output (0L); break; case CK_Debug_Until_Curser: debug_until (0L); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?