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 + -
显示快捷键?