Allow to pass an executable file via lldb-mi arguments (MI)

Summary:
# Allow to pass an executable file via lldb-mi arguments
# Add tests
# Fix (gdb) prompt in CMIDriver::LocalDebugSessionStartupExecuteCommands
# Fix prompt in CMIDriver::InterpretCommandThisDriver: use the lldb-mi prompt instead of a hard-coded value.

All tests pass on OS X.

Reviewers: abidh, clayborg

Reviewed By: clayborg

Subscribers: lldb-commits, clayborg, abidh

Differential Revision: http://reviews.llvm.org/D8001

llvm-svn: 231070
This commit is contained in:
Ilia K 2015-03-03 15:14:32 +00:00
parent d207f17fa1
commit c6c716ac9d
5 changed files with 165 additions and 6 deletions

View File

@ -0,0 +1,5 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,136 @@
"""
Test lldb-mi startup options.
"""
# adjust path for lldbmi_testcase.py
import sys, os.path
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
import lldbmi_testcase
from lldbtest import *
import unittest2
class MiStartupOptionsTestCase(lldbmi_testcase.MiTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
@lldbmi_test
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_executable_option_file(self):
"""Test that 'lldb-mi --interpreter %s' loads executable file."""
self.spawnLldbMi(args = "%s" % self.myexe)
# Test that lldb-mi is ready after startup
self.expect(self.child_prompt, exactly = True)
# Test that the executable is loaded when file was specified
self.expect("-file-exec-and-symbols \"%s\"" % self.myexe)
self.expect("\^done")
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly = True)
# Run
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"exited-normally\"")
@lldbmi_test
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_executable_option_unknown_file(self):
"""Test that 'lldb-mi --interpreter %s' fails on unknown executable file."""
# Prepare path to executable
path = "unknown_file"
self.spawnLldbMi(args = "%s" % path)
# Test that lldb-mi is ready after startup
self.expect(self.child_prompt, exactly = True)
# Test that the executable isn't loaded when unknown file was specified
self.expect("-file-exec-and-symbols \"%s\"" % path)
self.expect("\^error,msg=\"Command 'file-exec-and-symbols'. Target binary '%s' is invalid. error: unable to find executable for '%s'\"" % (path, path))
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly = True)
@lldbmi_test
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_executable_option_absolute_path(self):
"""Test that 'lldb-mi --interpreter %s' loads executable which is specified via absolute path."""
# Prepare path to executable
import os
path = os.path.join(os.getcwd(), self.myexe)
self.spawnLldbMi(args = "%s" % path)
# Test that lldb-mi is ready after startup
self.expect(self.child_prompt, exactly = True)
# Test that the executable is loaded when file was specified using absolute path
self.expect("-file-exec-and-symbols \"%s\"" % path)
self.expect("\^done")
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly = True)
# Run
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"exited-normally\"")
@lldbmi_test
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_executable_option_relative_path(self):
"""Test that 'lldb-mi --interpreter %s' loads executable which is specified via relative path."""
# Prepare path to executable
path = "./%s" % self.myexe
self.spawnLldbMi(args = "%s" % path)
# Test that lldb-mi is ready after startup
self.expect(self.child_prompt, exactly = True)
# Test that the executable is loaded when file was specified using relative path
self.expect("-file-exec-and-symbols \"%s\"" % path)
self.expect("\^done")
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly = True)
# Run
self.runCmd("-exec-run")
self.expect("\^running")
self.expect("\*stopped,reason=\"exited-normally\"")
@lldbmi_test
@expectedFailureWindows("llvm.org/pr22274: need a pexpect replacement for windows")
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
def test_lldbmi_executable_option_unknown_path(self):
"""Test that 'lldb-mi --interpreter %s' fails on executable file which is specified via unknown path."""
# Prepare path to executable
path = "unknown_dir/%s" % self.myexe
self.spawnLldbMi(args = "%s" % path)
# Test that lldb-mi is ready after startup
self.expect(self.child_prompt, exactly = True)
# Test that the executable isn't loaded when file was specified using unknown path
self.expect("-file-exec-and-symbols \"%s\"" % path)
self.expect("\^error,msg=\"Command 'file-exec-and-symbols'. Target binary '%s' is invalid. error: unable to find executable for '%s'\"" % (path, path))
# Test that lldb-mi is ready when executable was loaded
self.expect(self.child_prompt, exactly = True)
if __name__ == '__main__':
unittest2.main()

View File

@ -0,0 +1,14 @@
//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
int
main(int argc, char const *argv[])
{
return 0;
}

View File

@ -47,4 +47,4 @@
#define MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED 1 #define MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED 1
// 1 = Enable MI Driver in MI mode to create a local debug session, 0 = Report "Not implemented" // 1 = Enable MI Driver in MI mode to create a local debug session, 0 = Report "Not implemented"
#define MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION 0 #define MICONFIG_ENABLE_MI_DRIVER_MI_MODE_CMDLINE_ARG_EXECUTABLE_DEBUG_SESSION 1

View File

@ -913,11 +913,12 @@ CMIDriver::InterpretCommandThisDriver(const CMIUtilString &vTextLine, bool &vwbC
const CMICmnMIValueConst vconst = CMICmnMIValueConst(msg); const CMICmnMIValueConst vconst = CMICmnMIValueConst(msg);
const CMICmnMIValueResult valueResult("msg", vconst); const CMICmnMIValueResult valueResult("msg", vconst);
const CMICmnMIResultRecord miResultRecord(cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, valueResult); const CMICmnMIResultRecord miResultRecord(cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, valueResult);
m_rStdOut.WriteMIResponse(miResultRecord.GetString()); bool bOk = m_rStdOut.WriteMIResponse(miResultRecord.GetString());
m_rStdOut.WriteMIResponse("(gdb)"); if (bOk && m_rStdin.GetEnablePrompt())
bOk = m_rStdOut.WriteMIResponse(m_rStdin.GetPrompt());
// Proceed to wait for or execute next command // Proceed to wait for or execute next command
return MIstatus::success; return bOk;
} }
//++ ------------------------------------------------------------------------------------ //++ ------------------------------------------------------------------------------------
@ -1173,8 +1174,11 @@ bool
CMIDriver::LocalDebugSessionStartupExecuteCommands(void) CMIDriver::LocalDebugSessionStartupExecuteCommands(void)
{ {
const CMIUtilString strCmd(CMIUtilString::Format("-file-exec-and-symbols \"%s\"", m_strCmdLineArgExecuteableFileNamePath.AddSlashes().c_str())); const CMIUtilString strCmd(CMIUtilString::Format("-file-exec-and-symbols \"%s\"", m_strCmdLineArgExecuteableFileNamePath.AddSlashes().c_str()));
const bool bOk = CMICmnStreamStdout::TextToStdout(strCmd); bool bOk = CMICmnStreamStdout::TextToStdout(strCmd);
return (bOk && InterpretCommand(strCmd)); bOk = bOk && InterpretCommand(strCmd);
if (bOk && m_rStdin.GetEnablePrompt())
bOk = m_rStdOut.WriteMIResponse(m_rStdin.GetPrompt());
return bOk;
} }
//++ ------------------------------------------------------------------------------------ //++ ------------------------------------------------------------------------------------