Exemplo n.º 1
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);
}
Exemplo n.º 2
0
// Load history from history file
void load_history(const string& file)
{
    if (file.empty())
	return;

    // Delay d;

    std::ifstream is(file.chars());
    if (is.bad())
	return;

    static const StringArray empty;
    gdb_history = empty;

#if WITH_READLINE
    clear_history();
#endif

    assert(gdb_history.size() == 0);

    // If the first command in history is a `file' command,
    // insert them all and disregard later ones.
    bool first_command = true;
    bool first_is_file = false;
    bool get_files     = true;

    while (is)
    {
	// We accept lines up to a length of ARG_MAX (the maximum
	// length of the ARGV argument passed to a program)
	char _line[ARG_MAX + BUFSIZ];
	_line[0] = '\0';

	is.getline(_line, sizeof(_line));
	if (_line[0] != '\0')
	{
	    string line(_line);

	    bool added = false;
	    if (is_file_cmd(line, gdb) && line != "# reset")
	    {
		if (first_command)
		    first_is_file = true;

		if (get_files)
		{
		    string arg = line.after(rxwhite);
		    if (gdb->type() == PERL)
		    {
			arg = arg.after(" -d ");
			arg = arg.before('\"');
			if (arg.contains(rxwhite))
			    arg = arg.before(rxwhite);
		    }
		    add_to_recent(arg);
		    added = first_is_file;
		}
	    }
	    else
	    {
		if (first_is_file)
		    get_files = false;
		if (first_command)
		    first_is_file = false;
	    }

	    if (!added && line[0] != '#')
	    {
		gdb_history += line;
		add_to_arguments(line);

#if WITH_READLINE
		add_history(line.chars());
#endif
	    }

	    first_command = false;
	}
    }

    gdb_history += "";
    gdb_current_history = gdb_history.size() - 1;
    gdb_new_history = true;

    update_arguments();
    update_combo_boxes();
}