debug.c

来自「具有IDE功能的编辑器」· C语言 代码 · 共 1,371 行 · 第 1/3 页

C
1,371
字号
	CRedrawFieldedTextbox ("debug_vars", 1);    }    r = strchr (p, ':');    if (!r)	return;    r += 2;    p = strchr (r, '\n');    if (!p)	return;    *p++ = '\0';    p = strchr (p, '=');    if (!p)	return;    p += 2;    q = strchr (p, '\n');    if (!q)	return;    *q++ = '\0';    q = strchr (q, '=');    if (!q)	return;    q += 2;    *(strchr (q, '\n')) = '\0';    s = malloc (strlen (p) + strlen (q) + 100);    strcpy (s, _ ("Variable: "));    strcat (s, r);    strcat (s, "\n\n");    strcat (s, p);    strcat (s, "\n     --->     \n");    strcat (s, q);    debug_message (d, _ (" Watchpoint "), s, TEXT_CENTRED);    free (s);}static void debug_read_callback (int fd, fd_set * reading, fd_set * writing, fd_set * error, void *data){    Debug *d;    char *p;    char buf[1025];    int c, action, n;    d = &debug_session;    if (CChildExitted (d->pid, 0) || (!rxvt_have_pid (d->xterm_pid) && d->show_output)) {	debug_finish (0);	return;    }    do {	c = read (d->out, buf, 1024);    } while (c < 0 && errno == EINTR);    if (c <= 0)	return;    buf[c] = '\0';    for (n = 0; d->query[n].query; n++) {	if (from_end (buf, d->query[n].query, 1)) {	    p = strrchr (buf, '\n');	    if (!p)		buf[0] = '\0';	    else		p[1] = '\0';	    while (write (d->in, d->query[n].response, strlen (d->query[n].response)) < 0 && errno == EINTR);	    break;	}    }    n = 0;    if (!d->pool)	d->pool = pool_init ();    pool_printf (d->pool, "%s", buf);    if (d->show_on_stdout) {	printf ("%s", buf);	fflush (stdout);    }    if (!d->action)	goto fin_read;    p = from_end ((char *) pool_start (d->pool), d->prompt, 0);    if (!p)	return;			/* we have not found a prompt, so the command must not have completed */    action = d->action;    d->action = 0;    *p = '\0';    switch (action) {    case ACTION_PROMPT:	/* just waiting for the prompt to return, then command is completed */	pool_free (d->pool);	d->pool = 0;	break;    case ACTION_QUIT:    case ACTION_MESSAGE:	/* There was message from this command, display it */	if (strspn ((char *) pool_start (d->pool), "\n\t \r") != strlen ((char *) pool_start (d->pool)))	    debug_error1 (d, (char *) pool_start (d->pool));	pool_free (d->pool);	d->pool = 0;	if (action == ACTION_QUIT)	    debug_finish (0L);	break;    case ACTION_VERSION:/* 4.18 doesn't seem to do next's properly */	if (!strstr ((char *) pool_start (d->pool), GDB_VERSION1) && !strstr ((char *) pool_start (d->pool), GDB_VERSION3))	    debug_error1 (d, catstrs (GDB_VERSION1 " or " GDB_VERSION3, _ (" expected. You seem to have a different debugger \n or version. If things don't work properly, this is why."), 0));	if (!d->pool)	/* process was terminated */	    break;	if (from_end ((char *) pool_start (d->pool), "no debugging symbols found", 6)) {	    debug_error1 (d, _ ("The debugger returned \"no debugging symbols found\" implying that \n the executable has been stripped, or was not compiled with \n the \"-g\" option for debugging"));	    debug_finish (0L);	    break;	}	pool_free (d->pool);	d->pool = 0;	break;    case ACTION_WATCH:	p = strstr ((char *) pool_start (d->pool), "watchpoint");	if (p) {	    d->variable[d->break_point_line].watch = atoi (p + 11);	} else {	    d->variable[d->break_point_line].watch = 0;	}	CRedrawFieldedTextbox ("debug_vars", 1);	pool_free (d->pool);	d->pool = 0;	break;    case ACTION_VARIABLE:    case ACTION_LASTVAR:	xdebug_display_variable (d, (char *) pool_start (d->pool), action);	pool_free (d->pool);	d->pool = 0;	break;    case ACTION_CONDITION:    case ACTION_BREAKPOINT:	if (from_start ((char *) pool_start (d->pool), "No symbol table is loaded", 2)) {	    debug_error1 (d, _ ("The debugger returned \"No symbol table is loaded\" \n implying that the executable does not \n exist or is badly formatted"));	    debug_finish (0L);	    break;	}	if (from_start ((char *) pool_start (d->pool), "Function \"main\" not defined", 2) ||	    from_start ((char *) pool_start (d->pool), "No source file specified", 2)) {	    debug_error1 (d, _ ("The debugger returned a message implying that \n the executable was not compiled with \n the \"-g\" option for debugging"));	    debug_finish (0L);	    break;	}	p = strstr ((char *) pool_start (d->pool), "Breakpoint ");	if (p) {	    p += 11;	    n = atoi (p);	    p += strspn (p, "0123456789");	    p = from_start (p, " at ", 0);	}	if (p && action == ACTION_CONDITION) {	    char *q;	    q = malloc (strlen (d->condition) + 30);	    sprintf (q, "condition %d %s\n", n, d->condition);	    free (d->condition);	    d->condition = 0;	    xdebug_append_command (&debug_session, q, ACTION_MESSAGE, 0, 0);	    free (q);	} {	    CWidget *w;	    w = CIdent (d->break_point_editor);	    if (p) {		if (w) {		    if (!book_mark_query_color (w->editor, d->break_point_line - 1, DEBUG_BREAKPOINT_COLOR)) {			book_mark_insert (w->editor, d->break_point_line - 1, DEBUG_BREAKPOINT_COLOR);			w->editor->force |= REDRAW_COMPLETELY;			edit_render_keypress (edit[current_edit]->editor);		    }		}	    } else {		p = from_start ((char *) pool_start (d->pool), "Deleted breakpoint", 2);		if (!p)		    p = from_start ((char *) pool_start (d->pool), "No breakpoint ", 2);		if (!p)		    p = from_start ((char *) pool_start (d->pool), "No source file named ", 2);		if (p && w) {		    while (!book_mark_clear (w->editor, d->break_point_line - 1, DEBUG_BREAKPOINT_COLOR));		    w->editor->force |= REDRAW_COMPLETELY;		    edit_render_keypress (w->editor);		}	    }	}	if (!p) {	    if (strlen ((char *) pool_start (d->pool)))		debug_error1 (d, (char *) pool_start (d->pool));	    if (!d->pool)		break;	    xdebug_flush_commands (d);	}	if (p)	    xdebug_show_variables (d);	pool_free (d->pool);	d->pool = 0;	break;    case ACTION_INFO_SOURCE:	if (d->file) {	    free (d->file);	    d->file = 0;	}	p = strstr ((char *) pool_start (d->pool), "Located in ");	if (p) {	    char *q;	    q = p + 11;	    p = strchr (q, '\n');	    if (p) {		*p = '\0';		d->file = (char *) strdup (q);	    }	}	p = strstr ((char *) pool_start (d->pool), "No current source file");	if (p) {	    xdebug_cursor_bookmark_flush ();	} else {	    if (d->file && d->line)	/* if we can't get the file number, issue a backtrace */		xdebug_goto_line (d, d->file, d->line);	    else		xdebug_append_command (d, d->get_backtrace, ACTION_BACKTRACE, 0, 0);	}	pool_free (d->pool);	d->pool = 0;	break;    case ACTION_INFO_PROGRAM:	p = strstr ((char *) pool_start (d->pool), "Pid");	if (!p)	    p = strstr ((char *) pool_start (d->pool), "Thread");/* BUG FIX - gdb 5.0 says process instead of Pid */	if (!p)	    p = strstr ((char *) pool_start (d->pool), "process");/* end BUG FIX */	if (p) {	    p += strcspn (p, "0123456789");	    d->child = atoi (p);	}	if ((p = strstr ((char *) p, "LWP"))) {	    p += strcspn (p, "0123456789");	    d->child = atoi (p);	}	pool_free (d->pool);	d->pool = 0;	break;    case ACTION_BACKTRACE:    case ACTION_SHOW:	p = strstr ((char *) pool_start (d->pool), "No stack");	if ((unsigned long) p == (unsigned long) pool_start (d->pool)) {	    debug_error1 (d, _ (" There is no stack "));	    pool_free (d->pool);	} else {	    goto_file_dialog (action == ACTION_BACKTRACE ? _ (" Backtrace ") : _ (" Output "), 0, (char *) pool_break (d->pool));	}	d->pool = 0;	break;    case ACTION_STEP:    case ACTION_RUNNING:    case ACTION_UNTIL:	for (p = (char *) pool_start (d->pool); p; p++) {	    if (!*p)		break;            if (!strncmp (p, "0x", 2)) {/* {like: *//* 0x8060bd0       2110    return -1; } */                p += 2;                p += strspn (p, "0123456789abcdef");                while (*p == ' ' || *p == '\t')                    p++;            }	    if (*p >= '0' && *p <= '9')		d->line = atoi (p);	    p = strchr (p, '\n');	    if (!p)		break;	}	xdebug_check_watch_point (d, (char *) pool_start (d->pool));	p = from_end ((char *) pool_start (d->pool), "\nProgram exited normally", 3);	if (!p)	    p = from_end ((char *) pool_start (d->pool), "\nProgram exited with code", 7);	if (!p)	    p = from_end ((char *) pool_start (d->pool), "No such process", 7);	if (p) {	    xdebug_cursor_bookmark_flush ();	    d->child = 0;	}	if (!p) {		/* in all other circumstances, we must get the file and line number */	    if (d->line)	/* got the line, now be sure of the filename */		xdebug_append_command (d, d->get_source, ACTION_INFO_SOURCE, 0, 0);	    else		/* don't have the line, so show a backtrace */		xdebug_append_command (d, d->get_backtrace, ACTION_BACKTRACE, 0, 0);	    p = strstr ((char *) pool_start (d->pool), "\nProgram received signal");	}	if (!p) {		/* in all other circumstances, we must get the file and line number */	    p = from_start ((char *) pool_start (d->pool), "The program is not being run", 0);	    if (p) {		xdebug_cursor_bookmark_flush ();		d->child = 0;		if (action == ACTION_UNTIL)		    xdebug_break_point (d, "clear", d->break_point_editor, d->break_point_line + 1);	    }	}	if (p) {	    debug_error1 (d, p);	} else if (action == ACTION_UNTIL) {	    xdebug_break_point (d, "clear", d->break_point_editor, d->break_point_line + 1);	}	pool_free (d->pool);	d->pool = 0;	xdebug_show_variables (d);	break;    default:	break;    }  fin_read:    if (d->n_commands && !d->action)	CAddWatch (d->in, debug_write_callback, WATCH_WRITING, 0);}static void debug_write_callback (int fd, fd_set * reading, fd_set * writing, fd_set * error, void *data){    Debug *d;    int c;    d = &debug_session;    if (CChildExitted (d->pid, 0) || (!rxvt_have_pid (d->xterm_pid) && d->show_output)) {	debug_finish (0);	return;    }    if (d->show_on_stdout) {	printf ("%s", d->command[0].command);	fflush (stdout);    }    if (d->break_point_editor)	free (d->break_point_editor);    d->break_point_editor = 0;    d->break_point_line = 0;/* no backtrace if no program running, all other commands are ok */    if (!(!d->child && (d->command[0].action == ACTION_INFO_SOURCE || d->command[0].action == ACTION_BACKTRACE))) {	do {	    c = write (d->in, d->command[0].command, strlen (d->command[0].command));	} while (c < 0 && errno == EINTR);	d->action = d->command[0].action;	d->break_point_editor = d->command[0].editor;	d->break_point_line = d->command[0].line;    }    free (d->command[0].command);    if (d->action == ACTION_RUNNING || d->action == ACTION_STEP || d->action == ACTION_UNTIL)	xdebug_cursor_bookmark_flush ();    memmove (&d->command[0], &d->command[1], d->n_commands * sizeof (struct _command));    d->command[d->n_commands].action = 0;    d->command[d->n_commands].command = 0;    d->n_commands--;    CRemoveWatch (d->in, debug_write_callback, WATCH_WRITING);}static int xdebug_run_program (Debug * d){    char *arg[10];    int i = 0;    struct stat s;    xdebug_cursor_bookmark_flush ();    if (stat (d->progname, &s)) {	debug_error2 (d,		      _		      ("Error trying to stat executable: check that the filename and \n current directory are correct"),		      strerror (errno));	return 1;	if (!(s.st_mode & S_IXUSR)) {	    debug_error2 (d, _("Your program does not seem to have execute permissions"),			  d->progname);	    return 1;	}    }    arg[i++] = d->debugger;    if (d->show_output) {	char *p, *gargv[2] = {0, 0};	void *rxvt;        gargv[0] = d->progname;	rxvt = (void *) rxvt_start (CRoot, gargv, 1);	if (!rxvt) {	    d->xterm_pid = 0;	    d->pid = 0;	    debug_error1 (d, _("Could not open an rxvt"));	    xdebug_flush_commands (d);	    return 1;	}	p = (char *) strdup ("-tty=                    ");	rxvt_get_tty_name (rxvt, p + 5);	d->xterm_pid = (pid_t) rxvt_get_pid (rxvt);	arg[i++] = p;	arg[i++] = d->progname;	arg[i] = 0;	d->pid = triple_pipe_open (&d->in, &d->out, 0, 1, d->debugger, arg);	free (p);    } else {	char *p;	p = (char *) strdup ("-tty=                    ");	arg[i++] = p;	arg[i++] = d->progname;	arg[i] = 0;	d->pid = open_under_pty (&d->in, &d->out, p + 5, d->debugger, arg);	free (p);    }    if (d->pid <= 0) {	d->pid = 0;	if (d->xterm_pid)	    kill (d->xterm_pid, SIGTERM);	d->xterm_pid = 0;	d->pid = 0;	debug_error1 (d, _("Could not open gdb"));	xdebug_flush_commands (d);	return 1;    }    d->child = 0;    d->action = ACTION_VERSION;    CAddWatch (d->out, debug_read_callback, WATCH_READING, 0);    return 0;}static void xdebug_set_args (Debug * d, char *args){    char *s;    s = malloc (strlen (args) + 20);    sprintf (s, "set args %s\n", args ? args : "");    xdebug_append_command (d, s, ACTION_PROMPT, 0, 0);    free (s);}static void xdebug_run (Debug * d){    char s[80];    xdebug_append_command (d, "b main\n", ACTION_BREAKPOINT, 0, 0);    xdebug_append_command (d, "r\n", ACTION_RUNNING, 0, 0);    xdebug_append_command (d, "clear\n", ACTION_BREAKPOINT, 0, 0);/* programs get this signal when they ioctl the terminal given to them by gdb *//* this prevents them quiting when using the `show output' option */    if (d->ignore_SIGTTOU) {	sprintf (s, "call signal (%d, (void *) %lu)\n", SIGTTOU, (unsigned long) SIG_IGN);	xdebug_append_command (d, s, ACTION_PROMPT, 0, 0);    }    xdebug_append_command (d, "info program\n", ACTION_INFO_PROGRAM, 0, 0);    if (!d->stop_at_main)	xdebug_append_command (d, "c\n", ACTION_RUNNING, 0, 0);}static void debug_start (void){    if (xdebug_run_program (&debug_session))	return;    xdebug_set_args (&debug_session, debug_session.args);/*    xdebug_set_watch_points (&debug_session);	*/    xdebug_set_break_points (&debug_session);    xdebug_run (&debug_session);}static int debug_set_info (unsigned long x);static void debug_attach (unsigned long x){    char *s;    char t[80];    long p;    if (debug_session.pid) {	debug_error1 (&debug_session, _ ("Debugger is current running, use Kill or Detach first"));	return;    }    if (debug_session.action) {	debug_error1 (&debug_session, _ ("Program is currently running, use Control-C first"));	return;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?