/* Recursively remove all file/directories under dir/subdir. If save_dir is set, move any core files there. */ int nuke_dir_subdir(const char *dirpath, const char *subdir, const char *savedir) { int dlen, nlen; char *path; DIR *dir; struct dirent *de; int ret; if (!dirpath || !*dirpath) { return -1; } if (!subdir) { subdir = ""; } dlen = strlen(dirpath); nlen = strlen(subdir); path = alloca(dlen + nlen + 2); strcpy (path, dirpath); if (*subdir) { char *cp = path + dlen; *cp++ = '/'; strcpy (cp, subdir); } dir = opendir(path); if (!dir) { D_PRINTF(stderr, "Error removing contents of '%s': %s\n", path, strerror(errno)); rmdir(path); /* attempt to rmdir anyway */ return -1; } while ((de = readdir(dir))) { // Note that errors are intentionally ignored. if (de->d_type == DT_DIR) { if (0 == strcmp(".", de->d_name)) continue; if (0 == strcmp("..", de->d_name)) continue; nuke_dir_subdir (path, de->d_name, savedir); } else { if (savedir && is_core_file(de->d_name)) { if (move_dir_file (path, savedir, de->d_name) >= 0) continue; } unlink_dir_file (path, de->d_name); } } closedir(dir); ret = rmdir(path); /* fails if directory not empty */ if (ret < 0) { D_PRINTF(stderr, "Error removing dir '%s'\n", path); } return ret; }
// Get information on current debuggee ProgramInfo::ProgramInfo() : file(NO_GDB_ANSWER), core(NO_GDB_ANSWER), pid(0), attached(false), running(false), state() { if (source_view->have_exec_pos()) { state = "has stopped"; running = true; } else { state = "is not being run"; running = false; } switch(gdb->type()) { case GDB: case PYDB: case DBG: { string ans; if (gdb->is_windriver_gdb()) { // Windriver GDB (VxWorks). // VxWorks allows multiple dynamically relocatable // programs to be loaded simultaneously. Before a program // is run, the 'info source' command can report // information from a source file not related to the // program just downloaded for debugging. (The WindRiver // version of gdb does not support the 'info files' // command.) // In order to tell DDD that there is indeed a source file // available, we need to first see if a program has // already been started. If so, then the 'info source' // command can be used. // Otherwise, the 'info sources' command is used, and the // first file in the list is used, assuming it is related // to the current program that was downloaded. // See if the program has been run first ans = gdb_question("info frame"); if (ans == NO_GDB_ANSWER) break; file = ""; if (ans.contains("No stack")) { // Then try using info sources and use first file listed ans = gdb_question("info sources"); if (ans == NO_GDB_ANSWER) break; if (ans.contains("Source files for which " "symbols have been read in:")) { file = ans.after("\n"); file = file.before(" "); file = unquote(file); } } else { // Try using `info source'. ans = gdb_question("info source"); if (ans == NO_GDB_ANSWER) break; if (ans.contains("Current source file is ")) { file = ans.after("Current source file is "); file = file.before(".\n"); file = unquote(file); } } } else { // Ordinary GDB. ans = gdb_question("info files"); if (ans == NO_GDB_ANSWER) break; file = ""; if (ans.contains("Symbols from ")) { file = ans.after("Symbols from "); file = file.before(".\n"); file = unquote(file); } } core = ""; if (ans.contains("core dump")) { core = ans.after("core dump"); core = core.after('`'); core = core.before("',"); } if (ans.contains("process ")) { string p = ans.after("process "); pid = atoi(p.chars()); } attached = ans.contains("attached process "); ans = gdb_question("info program"); if (ans == NO_GDB_ANSWER) break; if (ans.contains("not being run")) running = false; else if (ans.contains("\nIt stopped ")) { state = ans.from("\nIt stopped "); state = "has " + state.after("\nIt "); state = state.before('.'); running = true; } break; } case DBX: { if (gdb->is_ladebug()) { string ans = gdb_question("show process"); // typical answers: // 1:no process // There are no processes being debugged. // 2: process has been paused. // Current Process: localhost:26177 (a.out) paused. // 3: process terminated // Current Process: localhost:13614 (ddd) terminated. // TODO: treat the terminated case if (ans != NO_GDB_ANSWER && !ans.contains("no processes being debugged")) { if (ans.contains("Current Process: ")) { ans = ans.after(": "); { string p = ans.after(":"); p = p.before(" "); pid = atoi(p.chars()); } ans = ans.after(" ("); file = ans.before(")"); ans = ans.after(") "); running = ans.contains("paused"); // ladebug always creates a process. // It may be "loaded" or attached. attached = true; } } } // AD TODO: shouldn't it be an "else" ? string ans = gdb_question(gdb->debug_command()); if (ans != NO_GDB_ANSWER) { if (ans.contains("Current givenfile is ", 0)) ans = ans.after("Current givenfile is "); else if (ans.contains("Debugging: ", 0)) ans = ans.after(": "); strip_space(ans); if (!ans.contains(' ')) // Sanity check file = ans; } break; } case XDB: break; // FIXME case PERL: // Use the program we were invoked with file = gdb->program(); if (file.matches(rxint)) file = ""; // Invoked with a constant expression if (file.empty()) { // Not invoked with a program? Use the current file, then. file = source_view->file_of_cursor(); file = file.before(":"); } core = ""; break; case BASH: // Use the program we were invoked with file = gdb->program(); if (file.matches(rxint)) file = ""; // Invoked with a constant expression if (file.empty()) { // Not invoked with a program? Use the current file, then. file = source_view->file_of_cursor(); file = file.before(":"); } core = ""; break; case JDB: // Just use the current class. file = source_view->line_of_cursor(); file = file.before(":"); core = ""; // Save whether JDB's VM is running static int last_jdb_pid = -1; static bool jvm_running = false; if (gdb->pid() != last_jdb_pid) { // New JDB: reset info jvm_running = false; last_jdb_pid = gdb->pid(); } // The VM is running iff the prompt contains a backtrace // level ("[n]"). if (!jvm_running && gdb->prompt().contains("[")) jvm_running = true; running = jvm_running; break; } if (file == NO_GDB_ANSWER) { // As a fallback, get core file and executable from argument list. // Works only on local file system and is more a guess. char **argv = saved_argv(); int argc = 0; while (argv[argc] != 0) argc++; for (int i = argc - 1; i > 0 && file == NO_GDB_ANSWER; i--) { // All debuggers supported by DDD have [EXEC [CORE]] as // their last arguments. string arg = argv[i]; if (is_core_file(arg)) core = arg; else if (is_debuggee_file(arg)) file = arg; } } if (file != NO_GDB_ANSWER) add_to_recent(file); }