📄 gdb_handler.c
字号:
if (LineToStop_no(line) == 0) RemoveStop(line); } }}/* this handler justs update the function name.Because the function name is not always displayedafter next,step ... */static char* funcname = 0;void frame_curr_handler(){ if (Token.func == NULL) return; if (funcname) { XtFree(funcname); funcname = 0; } funcname = XtNewString(Token.func);}/* Handle dbx output of run, cont, next, step, return commands. * Result of output parsing is returned in a set of tokens. * * If message is not 0, this is an important message and should * be displayed instead of Token.mesg. * This message will hold the Bus error and segmentation violation errors. * signal is the signal number received (if any). */void exec_handler(message,signal)char *message;int signal;{ int line, status; char *func; /* Print "stopped in ..." line in message window * Adjust text displayed */ if (Token.line == 0) return; if (message) UpdateMessageWindow(message,NULL); else UpdateMessageWindow(Token.mesg,NULL); line = Token.line; func = (Token.func) ? XtNewString(Token.func) : 0; if (Token.file) status = LoadFile(Token.file); else status = -1; /* AJK */ display_info_handler(); /* uses Token.display ! */ /* because of tbreak, we have to call info break here */ query_gdb("info break\n", PARSE_ON | ECHO_OFF | FILTER_OFF); /* update breakpoints */ if (func == NULL) { /* because silly gdb 4.0 displays nothing with frame command when confirm is on (possibly a gdb bug) , I just reset confirm to on just for this command !. */ if (new_gdb4()) query_gdb("set confirm on\n", PARSE_OFF | ECHO_OFF | FILTER_OFF); /* this will just update funcname (see frame_curr_handler()) */ query_gdb("frame\n", PARSE_ON | ECHO_OFF | FILTER_OFF); if (new_gdb4()) /* reset confirm to off */ query_gdb("set confirm off\n", PARSE_OFF | ECHO_OFF | FILTER_OFF); func = funcname; if (func == NULL) return; funcname = 0; /* tell frame_curr_handler WE are going to XtFree it */ } arrow.line = line; /* update arrow sign position */ strcpy(arrow.func, func); updown.line = 0; /* remove updown, if any */ if (displayedFile) { strcpy(arrow.file, displayedFile->pathname); } /* Display bomb sign if segmentation fault occurs in source code */ if (status != -1 && message && signal == SIGSEGV) { arrow.line = 0; bomb.line = line; if (func) strcpy(bomb.func, func); if (displayedFile) strcpy(bomb.file, displayedFile->pathname); } else bomb.line = 0; AdjustText(line); XtFree(func);}/* Remove all the arrow and updown signs, print message, then * change the file variable to the file name displayed. *//* ARGSUSED */void done_handler(message,signal)char *message;int signal;{ arrow.line = 0; updown.line = 0; UpdateArrow(displayedFile); UpdateUpdown(displayedFile); UpdateMessageWindow("Ready for execution",NULL);}/*--------------------------------------------------------------------------+| || Function to read the .gdbinit file or any source file. || || input : file name. || || output : none. || |+--------------------------------------------------------------------------*/void read_source_file(file)char *file;{char s[LINESIZ];FILE *fp; if ((fp = fopen(file, "r"))) { while (fgets(s, LINESIZ, fp)) { /* Check for comment line, DO NOT SEND '\n', Take care of source command, Take care of define or document commands. */ if ((*s != '#') && strcmp(s,"\n")) { if (!(gdb_source_command (s,TRUE) || gdb_define_command (s,fp) || xxgdb_command (s,TRUE))) /* send to gdb only if it is not source, define or an xxgdb command. */ query_gdb(s, PARSE_ON | ECHO_ON | FILTER_ON); } } fclose(fp); }}/* WARNING : source_handler() is NOT called by the parser.It is called by gdb_source_command() in gdb_parser.c.This is because 'source' command is NEVER sent to gdb,instead xxgdb sends the commands in the specified fileone by one. */void source_handler(){char *file; if (!Token.file || strcmp(Token.file, "") == 0) { XtFree(Token.file); Token.file = XtNewString(gdbinit); /* default is .gdbinit */ } file = GetPathname(Token.file); if (file == NULL) { /* error message already displayed by GetPathname() */ return; /* (PW)11JAN91 */ } read_source_file(file);}/* core-file * gdb does not display current line, file, func ..., so we send * 'frame 0' command to have them. */void core_file_handler(){ char *message; int line; int signal; message = XtNewString(Token.mesg); signal = Token.stop; /* signal number received */ /* because silly gdb 4.0 displays nothing with frame command when confirm is on (possibly a gdb bug) , I just reset confirm to on just for this command !. */ if (new_gdb4()) query_gdb("set confirm on\n", PARSE_OFF | ECHO_OFF | FILTER_OFF); /* this will update updown.line, updown.func and updown.file. (see updown_handler) */ query_gdb("frame 0\n", PARSE_ON | ECHO_OFF | FILTER_OFF); if (new_gdb4()) /* reset confirm to off */ query_gdb("set confirm off\n", PARSE_OFF | ECHO_OFF | FILTER_OFF); line = updown.line; updown.line = 0; /* Display bomb sign if segmentation fault occurred in source code */ if (line != 0 && signal == SIGSEGV) { arrow.line = 0; bomb.line = line; strcpy(bomb.func, updown.func); strcpy(bomb.file, updown.file); } else { bomb.line = 0; arrow.line = line; strcpy(arrow.func, updown.func); strcpy(arrow.file, updown.file); } UpdateMessageWindow(message,NULL); XtFree(message); AdjustText(line); }/*--------------------------------------------------------------------------+| || Function to get the current source path directories. || || WARNING : this function is called at startup of xxgdb || to test for gdb 4.0 or earlier versions. || The 1st time that query_gdb_directories() is called, || new_gdb is true, and 'show directories' command is || issued to gdb. Then parse() in gdb_parser.c will test for || 'show Unknown command' answer from gdb, and in that case || will set new_gdb to false. See show_is_undefined() below. || |+--------------------------------------------------------------------------*/void query_gdb_directories(){ if (new_gdb4()) /* (PW)28AUG91: test for gdb 4.0 */ query_gdb("show directories\n", PARSE_ON | ECHO_OFF | FILTER_OFF); else query_gdb("info directories\n", PARSE_ON | ECHO_OFF | FILTER_OFF);}/*--------------------------------------------------------------------------+| || Function to know if we are running the NEW gdb || || return TRUE if we are running gdb 4.0 (or 3.9x or higher) || || WARNING : it is important that the default is gdb 4.0. || (see comments on query_gdb_directories() above). || || (PW)(DS)19FEB92 NeXT : || gdb 3.1 for the NeXT OS 2.1 does not answer 'undefined command' when || trying to execute 'show'. That is why the test for gdb-4.x vs || gdb 3.x does not work in case of NeXT. Using gdb 3.x as default || will make xxgdb skip this test. || The gdb answer is "Ambiguous command "show": shownops, showps.". || |+--------------------------------------------------------------------------*/#if defined(NeXT) && defined(NEXTOS_2)static int new_gdb = False; /* special case for NeXT */#elsestatic int new_gdb = True; /* default : we are running gdb 4.0 */#endifint new_gdb4(){ return new_gdb;}/*--------------------------------------------------------------------------+| || Function to say that 'show' command is undefined and thus || that we are running an old version of gdb. || |+--------------------------------------------------------------------------*/void show_is_undefined(){ new_gdb = False;}/*--------------------------------------------------------------------------+| || Update compilation directory || || This function is used for gdb 4.0 which uses the compilation || directory in the source path. || || input : current compilation directory, || current source full path, || current source path. || (returned from 'info source' gdb command). || || output : none. || |+--------------------------------------------------------------------------*/char cdir[MAXPATHLEN]; /* The compilation directory */char source_fullpath[MAXPATHLEN]; /* The current source file full path */char source_path[MAXPATHLEN]; /* The current source file name */voidinfo_source_handler(compile_dir,current_source_path, current_source)char * compile_dir;char * current_source_path;char * current_source;{ cdir[0] = 0; if (compile_dir != NULL) { simplify_path (compile_dir); /* be sure to get only significant path */ if (strlen (compile_dir) < MAXPATHLEN) /* check length */ strcpy (cdir, compile_dir); else UpdateMessageWindow("Path too long \"%s\"", compile_dir); if (LASTCH(cdir) == '/') /* remove last '/' */ LASTCH(cdir) = '\0'; } source_fullpath[0] = 0; if (current_source_path != NULL) { simplify_path (current_source_path); /* be sure to get only significant path */ if (strlen (current_source_path) < MAXPATHLEN) /* check length */ strcpy (source_fullpath, current_source_path); else UpdateMessageWindow("Path too long \"%s\"", current_source_path); } source_path[0] = 0; if (current_source != NULL) { simplify_path (current_source); /* be sure to get only significant path */ if (strlen (current_source) < MAXPATHLEN) /* check length */ strcpy (source_path, current_source); else UpdateMessageWindow("Path too long \"%s\"", current_source); } if (debug) fprintf(stderr,"cdir = \"%s\"\nsource = \"%s\"\nsource full path = \"%s\"\n", cdir, source_path, source_fullpath);}/*--------------------------------------------------------------------------+| || Function to simplify a pathname : || || /. => / || /./xxx => /xxx || /foo/.. => / || /foo/../xxx => /xxx || foo/.. => . || foo/../ => . || foo/../xxx => xxx || xxx/ => xxx || |+--------------------------------------------------------------------------*/voidsimplify_path(path)char *path;{char *p;int len; for (p = path; *p;) { if (!strncmp (p, "/./", 2) && (p[2] == 0 || p[2] == '/')) { if (p[2] == 0 && p == path) /* '/.' => '/' */ *(p+1) = 0; /* keep first '/' */ else strcpy (p, p + 2); /* '/./xxx' => '/xxx' */ } else if (!strncmp (p, "/..", 3) && (p[3] == 0 || p[3] == '/') && p != path) { char *q = p; /* search previous '/' */ while (q != path && q[-1] != '/') q--; if (q != path) /* previous '/' was found */ { if (p[3] == 0 && (q-1) == path) /* '/foo/..'=> '/' */ *q = 0; /* keep first '/' */ else strcpy (q-1, p+3); /* '/foo/../xxx' => '/xxx' */ p = q-1; } else /* previous '/' was not found */ { /* 'foo/..' => '.' */ if (p[3] == 0 || p[4] == 0) /* 'foo/../' => '.' */ strcpy (path, "."); else /* 'foo/../xxx'=> xxx */ strcpy (path, p+4); } } else p++; } /* remove last '/' if not in first position */ len = strlen(path); if ((len > 1) && (path[len-1] == '/')) path[len-1] = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -