예제 #1
0
파일: files.c 프로젝트: thomoco/mstone
/* 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;
}
예제 #2
0
// 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);
}