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