162 changes: 162 additions & 0 deletions lldb/test/tools/lldb-mi/TestMiEvaluate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
"""
Test that the lldb-mi driver can evaluate expressions.
"""

import os
import unittest2
import lldb
from lldbtest import *

class MiEvaluateTestCase(TestBase):

mydir = TestBase.compute_mydir(__file__)
myexe = "a.out"

@classmethod
def classCleanup(cls):
"""Cleanup the test byproducts."""
try:
os.remove("child_send.txt")
os.remove("child_read.txt")
os.remove(cls.myexe)
except:
pass

@lldbmi_test
def test_lldbmi_eval(self):
"""Test that 'lldb-mi --interpreter' works for evaluating."""
import pexpect
self.buildDefault()

# The default lldb-mi prompt (seriously?!).
prompt = "(gdb)"

# So that the child gets torn down after the test.
self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
child = self.child
child.setecho(True)
# Turn on logging for input/output to/from the child.
with open('child_send.txt', 'w') as f_send:
with open('child_read.txt', 'w') as f_read:
child.logfile_send = f_send
child.logfile_read = f_read

child.send("-file-exec-and-symbols " + self.myexe)
child.sendline('')
child.expect("\^done")

#run to main
child.send("-break-insert -f main")
child.sendline('')
child.expect("\^done,bkpt={number=\"1\"")

child.send("-exec-run")
child.sendline('') #FIXME: hangs here; extra return below is needed
child.send("")
child.sendline('')
child.expect("\^running")
child.expect("\*stopped,reason=\"breakpoint-hit\"")

#run to program return
child.send("-break-insert main.c:30") #BP_source
child.sendline('')
child.expect("\^done,bkpt={number=\"2\"")

child.send("-exec-continue")
child.sendline('')
child.expect("\^running")
child.expect("\*stopped,reason=\"breakpoint-hit\"")

#print non-existant variable
#child.send("-var-create var1 --thread 1 --frame 0 * undef")
#child.sendline('') #FIXME: shows undef as {...}
#child.expect("error")
#child.send("-data-evaluate-expression undef")
#child.sendline('') #FIXME: gets value="undef"
#child.expect("error")

#print global "g_MyVar"
child.send("-var-create var1 --thread 1 --frame 0 * g_MyVar")
child.sendline('') #FIXME: shows name=<unnamedvariable>"
child.expect("value=\"3\",type=\"int\"")
#child.send("-var-evaluate-expression var1")
#child.sendline('') #FIXME: gets var1 does not exist
child.send("-var-show-attributes var1")
child.sendline('')
child.expect("status=\"editable\"")
child.send("-var-delete var1")
child.sendline('')
child.expect("\^done")
child.send("-var-create var1 --thread 1 --frame 0 * g_MyVar")
child.sendline('')
child.expect("value=\"3\",type=\"int\"")

#print static "s_MyVar" and modify
child.send("-data-evaluate-expression s_MyVar")
child.sendline('')
child.expect("value=\"30\"")
child.send("-var-create var3 --thread 1 --frame 0 * \"s_MyVar=3\"")
child.sendline('')
child.expect("value=\"3\",type=\"int\"")
child.send("-data-evaluate-expression \"s_MyVar=30\"")
child.sendline('')
child.expect("value=\"30\"")

#print local "b" and modify
child.send("-data-evaluate-expression b")
child.sendline('')
child.expect("value=\"20\"")
child.send("-var-create var3 --thread 1 --frame 0 * \"b=3\"")
child.sendline('')
child.expect("value=\"3\",type=\"int\"")
child.send("-data-evaluate-expression \"b=20\"")
child.sendline('')
child.expect("value=\"20\"")

#print "a + b"
child.send("-data-evaluate-expression \"a + b\"")
child.sendline('')
child.expect("value=\"30\"")
child.send("-var-create var3 --thread 1 --frame 0 * \"a + b\"")
child.sendline('')
child.expect("value=\"30\",type=\"int\"")

#print "argv[0]"
child.send("-data-evaluate-expression \"argv[0]\"")
child.sendline('')
child.expect("value=\"0x")
child.send("-var-create var3 --thread 1 --frame 0 * \"argv[0]\"")
child.sendline('')
child.expect("numchild=\"1\",value=\"0x.*\",type=\"const char \*\"")

#run to exit
child.send("-exec-continue")
child.sendline('')
child.expect("\^running")
child.expect("\*stopped,reason=\"exited-normally\"")
child.expect_exact(prompt)

child.send("quit")
child.sendline('')

# Now that the necessary logging is done, restore logfile to None to
# stop further logging.
child.logfile_send = None
child.logfile_read = None

with open('child_send.txt', 'r') as fs:
if self.TraceOn():
print "\n\nContents of child_send.txt:"
print fs.read()
with open('child_read.txt', 'r') as fr:
from_child = fr.read()
if self.TraceOn():
print "\n\nContents of child_read.txt:"
print from_child


if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()
115 changes: 115 additions & 0 deletions lldb/test/tools/lldb-mi/TestMiInterrupt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
"""
Test that the lldb-mi driver can interrupt and resume a looping app.
"""

import os
import unittest2
import lldb
from lldbtest import *

class MiInterruptTestCase(TestBase):

mydir = TestBase.compute_mydir(__file__)
myexe = "a.out"

@classmethod
def classCleanup(cls):
"""Cleanup the test byproducts."""
try:
os.remove("child_send.txt")
os.remove("child_read.txt")
os.remove(cls.myexe)
except:
pass

@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@lldbmi_test
def test_lldbmi_interrupt(self):
"""Test that 'lldb-mi --interpreter' interrupt and resume a looping app."""
import pexpect
self.buildDefault()

# The default lldb-mi prompt (seriously?!).
prompt = "(gdb)"

# So that the child gets torn down after the test.
self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
child = self.child
child.setecho(True)
# Turn on logging for input/output to/from the child.
with open('child_send.txt', 'w') as f_send:
with open('child_read.txt', 'w') as f_read:
child.logfile_send = f_send
child.logfile_read = f_read

child.send("-file-exec-and-symbols " + self.myexe)
child.sendline('')
child.expect("\^done")

#run to main
child.send("-break-insert -f main")
child.sendline('')
child.expect("\^done,bkpt={number=\"1\"")
child.send("-exec-run")
child.sendline('') #FIXME: hangs here; extra return below is needed
child.send("")
child.sendline('')
child.expect("\^running")
child.expect("\*stopped,reason=\"breakpoint-hit\"")

#set doloop=1 and run (to loop forever)
child.send("-data-evaluate-expression \"doloop=1\"")
child.sendline('')
child.expect("value=\"1\"")
child.send("-exec-continue")
child.sendline('')
child.expect("\^running")

#issue interrupt, set a bp, and resume
child.send("-exec-interrupt")
child.sendline('')
child.expect("\*stopped,reason=\"signal-received\"")
child.send("-break-insert loop.c:11")
child.sendline('')
child.expect("\^done,bkpt={number=\"2\"")
#child.send("-exec-resume")
#child.sendline('') #FIXME: command not recognized
child.send("-exec-continue")
child.sendline('')
child.expect("\*stopped,reason=\"breakpoint-hit\"")

#we should be sitting at loop.c:12
#set loop=-1 so we'll exit the loop
child.send("-data-evaluate-expression \"loop=-1\"")
child.sendline('')
child.expect("value=\"-1\"")
child.send("-exec-continue")
child.sendline('')
child.expect("\^running")
child.expect("\*stopped,reason=\"exited-normally\"")
child.expect_exact(prompt)

child.send("quit")
child.sendline('')

# Now that the necessary logging is done, restore logfile to None to
# stop further logging.
child.logfile_send = None
child.logfile_read = None

with open('child_send.txt', 'r') as fs:
if self.TraceOn():
print "\n\nContents of child_send.txt:"
print fs.read()
with open('child_read.txt', 'r') as fr:
from_child = fr.read()
if self.TraceOn():
print "\n\nContents of child_read.txt:"
print from_child


if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()
229 changes: 229 additions & 0 deletions lldb/test/tools/lldb-mi/TestMiLaunch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
"""
Test various ways the lldb-mi driver can launch a program.
"""

import os
import unittest2
import lldb
from lldbtest import *

class MiLaunchTestCase(TestBase):

mydir = TestBase.compute_mydir(__file__)
myexe = "a.out"

@classmethod
def classCleanup(cls):
"""Cleanup the test byproducts."""
try:
os.remove("child_send.txt")
os.remove("child_read.txt")
os.remove(cls.myexe)
except:
pass

@lldbmi_test
def test_lldbmi_exe(self):
"""Test that 'lldb-mi --interpreter' works for -file-exec-and-symbols exe."""
import pexpect
self.buildDefault()

# The default lldb-mi prompt (seriously?!).
prompt = "(gdb)"

# So that the child gets torn down after the test.
self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
child = self.child
child.setecho(True)
# Turn on logging for input/output to/from the child.
with open('child_send.txt', 'w') as f_send:
with open('child_read.txt', 'w') as f_read:
child.logfile_send = f_send
child.logfile_read = f_read

#use no path
child.send("-file-exec-and-symbols " + self.myexe)
child.sendline('')
child.expect("\^done")

child.send("-exec-run")
child.sendline('') # FIXME: lldb-mi hangs here, so the extra return below is needed
child.send("")
child.sendline('')
child.expect("\^running")
child.expect("\*stopped,reason=\"exited-normally\"")
child.expect_exact(prompt)

child.send("quit")
child.sendline('')

# Now that the necessary logging is done, restore logfile to None to
# stop further logging.
child.logfile_send = None
child.logfile_read = None

with open('child_send.txt', 'r') as fs:
if self.TraceOn():
print "\n\nContents of child_send.txt:"
print fs.read()
with open('child_read.txt', 'r') as fr:
from_child = fr.read()
if self.TraceOn():
print "\n\nContents of child_read.txt:"
print from_child

@lldbmi_test
def test_lldbmi_abspathexe(self):
"""Test that 'lldb-mi --interpreter' works for -file-exec-and-symbols fullpath/exe."""
import pexpect
self.buildDefault()

# The default lldb-mi prompt (seriously?!).
prompt = "(gdb)"

# So that the child gets torn down after the test.
self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
child = self.child
child.setecho(True)
# Turn on logging for input/output to/from the child.
with open('child_send.txt', 'w') as f_send:
with open('child_read.txt', 'w') as f_read:
child.logfile_send = f_send
child.logfile_read = f_read

#use full path
exe = os.path.join(os.getcwd(), "a.out")
child.send("-file-exec-and-symbols " + exe)
child.sendline('')
child.expect("\^done")

child.send("-exec-run")
child.sendline('') # FIXME: lldb-mi hangs here, so the extra return below is needed
child.send("")
child.sendline('')
child.expect("\^running")
child.expect("\*stopped,reason=\"exited-normally\"")
child.expect_exact(prompt)

child.send("quit")
child.sendline('')

# Now that the necessary logging is done, restore logfile to None to
# stop further logging.
child.logfile_send = None
child.logfile_read = None

with open('child_send.txt', 'r') as fs:
if self.TraceOn():
print "\n\nContents of child_send.txt:"
print fs.read()
with open('child_read.txt', 'r') as fr:
from_child = fr.read()
if self.TraceOn():
print "\n\nContents of child_read.txt:"
print from_child

@lldbmi_test
def test_lldbmi_relpathexe(self):
"""Test that 'lldb-mi --interpreter' works for -file-exec-and-symbols relpath/exe."""
import pexpect
self.buildDefault()

# The default lldb-mi prompt (seriously?!).
prompt = "(gdb)"

# So that the child gets torn down after the test.
self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
child = self.child
child.setecho(True)
# Turn on logging for input/output to/from the child.
with open('child_send.txt', 'w') as f_send:
with open('child_read.txt', 'w') as f_read:
child.logfile_send = f_send
child.logfile_read = f_read

#use relative path
exe = "../../" + self.mydir + "/" + self.myexe
child.send("-file-exec-and-symbols " + exe)
child.sendline('')
child.expect("\^done")

child.send("-exec-run")
child.sendline('') # FIXME: lldb-mi hangs here, so the extra return below is needed
child.send("")
child.sendline('')
child.expect("\^running")
child.expect("\*stopped,reason=\"exited-normally\"")
child.expect_exact(prompt)

child.send("quit")
child.sendline('')

# Now that the necessary logging is done, restore logfile to None to
# stop further logging.
child.logfile_send = None
child.logfile_read = None

with open('child_send.txt', 'r') as fs:
if self.TraceOn():
print "\n\nContents of child_send.txt:"
print fs.read()
with open('child_read.txt', 'r') as fr:
from_child = fr.read()
if self.TraceOn():
print "\n\nContents of child_read.txt:"
print from_child

@unittest2.skip("lldb-mi badpath hang")
@lldbmi_test
def test_lldbmi_badpathexe(self):
"""Test that 'lldb-mi --interpreter' works for -file-exec-and-symbols badpath/exe."""
import pexpect
self.buildDefault()

# The default lldb-mi prompt (seriously?!).
prompt = "(gdb)"

# So that the child gets torn down after the test.
self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
child = self.child
child.setecho(True)
# Turn on logging for input/output to/from the child.
with open('child_send.txt', 'w') as f_send:
with open('child_read.txt', 'w') as f_read:
child.logfile_send = f_send
child.logfile_read = f_read

#use relative path
exe = "badpath/" + self.myexe
#print ("-file-exec-and-symbols " + exe)
child.send("-file-exec-and-symbols " + exe)
child.sendline('') #FIXME: non-existant directory caused hang
child.expect("\^error")

child.expect_exact(prompt)

child.send("quit")
child.sendline('')

# Now that the necessary logging is done, restore logfile to None to
# stop further logging.
child.logfile_send = None
child.logfile_read = None

with open('child_send.txt', 'r') as fs:
if self.TraceOn():
print "\n\nContents of child_send.txt:"
print fs.read()
with open('child_read.txt', 'r') as fr:
from_child = fr.read()
if self.TraceOn():
print "\n\nContents of child_read.txt:"
print from_child


if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()
101 changes: 101 additions & 0 deletions lldb/test/tools/lldb-mi/TestMiProgramArgs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""
Test that the lldb-mi driver can pass arguments to the app.
"""

import os
import unittest2
import lldb
from lldbtest import *

class MiProgramArgsTestCase(TestBase):

mydir = TestBase.compute_mydir(__file__)
myexe = "a.out"

@classmethod
def classCleanup(cls):
"""Cleanup the test byproducts."""
try:
os.remove("child_send.txt")
os.remove("child_read.txt")
os.remove(cls.myexe)
except:
pass

@unittest2.skip("lldb-mi can't pass params to app.")
@lldbmi_test
def test_lldbmi_paramargs(self):
"""Test that 'lldb-mi --interpreter' can pass arguments to the app."""
import pexpect
self.buildDefault()

# The default lldb-mi prompt (seriously?!).
prompt = "(gdb)"

# So that the child gets torn down after the test.
self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
child = self.child
child.setecho(True)
# Turn on logging for input/output to/from the child.
with open('child_send.txt', 'w') as f_send:
with open('child_read.txt', 'w') as f_read:
child.logfile_send = f_send
child.logfile_read = f_read

child.send("-file-exec-and-symbols " + self.myexe)
child.sendline('')
child.expect("\^done")

#child.send("-exec-arguments l")
#child.sendline('') #FIXME: not recognized and hung lldb-mi
child.send("settings set target.run-args l")
child.sendline('') #FIXME: args not passed

#run to main
child.send("-break-insert -f main")
child.sendline('')
child.expect("\^done,bkpt={number=\"1\"")
child.send("-exec-run")
child.sendline('') #FIXME: hangs here; extra return below is needed
child.send("")
child.sendline('')
child.expect("\^running")
child.expect("\*stopped,reason=\"breakpoint-hit\"")

#check argc to see if arg passed
child.send("-data-evaluate-expression argc")
child.sendline('')
child.expect("value=\"2\"")

#set BP on code which is only executed if "l" was passed correctly
child.send("-break-insert main.c:27") #BP_argtest
child.sendline('')
child.expect("\^done,bkpt={number=\"2\"")
child.send("-exec-continue")
child.sendline('')
child.expect("\^running")
child.expect("\*stopped,reason=\"breakpoint-hit\"")

child.send("quit")
child.sendline('')

# Now that the necessary logging is done, restore logfile to None to
# stop further logging.
child.logfile_send = None
child.logfile_read = None

with open('child_send.txt', 'r') as fs:
if self.TraceOn():
print "\n\nContents of child_send.txt:"
print fs.read()
with open('child_read.txt', 'r') as fr:
from_child = fr.read()
if self.TraceOn():
print "\n\nContents of child_read.txt:"
print from_child

if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()
9 changes: 9 additions & 0 deletions lldb/test/tools/lldb-mi/a.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <stdio.h>

int
a_MyFunction ()
{
// Set a breakpoint here.
printf ("a is about to return 10.\n");
return 10;
}
9 changes: 9 additions & 0 deletions lldb/test/tools/lldb-mi/b.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <stdio.h>

int
b_MyFunction ()
{
// Set a breakpoint here.
printf ("b is about to return 20.\n");
return 20;
}
14 changes: 14 additions & 0 deletions lldb/test/tools/lldb-mi/loop.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <unistd.h>
int
infloop ()
{
int loop = 1;
while (loop > 0) {
if (loop > 10) {
sleep(1);
loop = 1;
}
loop++; // Set break point at this line.
}
return loop;
}
31 changes: 31 additions & 0 deletions lldb/test/tools/lldb-mi/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===-- main.c --------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <stdio.h>
extern int a_MyFunction();
extern int b_MyFunction();
extern int infloop();
int doloop;
int g_MyVar = 3;
static int s_MyVar = 4;
int main (int argc, char const *argv[])
{
int a, b;
printf("argc=%d\n", argc);
a = a_MyFunction();
b = b_MyFunction();
if (doloop)
infloop();
if (argc > 1 && *argv[1] == 'l') {
a++;
printf("a=%d, argv[1]=%s\n", a, argv[1]); //BP_argtest
}
s_MyVar = a + b;
return a + b - s_MyVar; //BP_source
}