Debugger: Make LLDB autotest produce output on Linux again

Change-Id: I0ea21b248b51a871753f66e386fd125df1d1ead5
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
hjk
2015-01-23 17:54:00 +01:00
parent 31fecb0820
commit 962649317b
2 changed files with 92 additions and 38 deletions

View File

@@ -1239,12 +1239,12 @@ class Dumper(DumperBase):
out = lldb.SBStream() out = lldb.SBStream()
event.GetDescription(out) event.GetDescription(out)
#warn("EVENT: %s" % event) #warn("EVENT: %s" % event)
type = event.GetType() eventType = event.GetType()
msg = lldb.SBEvent.GetCStringFromEvent(event) msg = lldb.SBEvent.GetCStringFromEvent(event)
flavor = event.GetDataFlavor() flavor = event.GetDataFlavor()
state = lldb.SBProcess.GetStateFromEvent(event) state = lldb.SBProcess.GetStateFromEvent(event)
self.report('event={type="%s",data="%s",msg="%s",flavor="%s",state="%s"}' self.report('event={type="%s",data="%s",msg="%s",flavor="%s",state="%s"}'
% (type, out.GetData(), msg, flavor, state)) % (eventType, out.GetData(), msg, flavor, state))
if state != self.eventState: if state != self.eventState:
self.eventState = state self.eventState = state
if state == lldb.eStateExited: if state == lldb.eStateExited:
@@ -1265,7 +1265,7 @@ class Dumper(DumperBase):
self.reportState("stopped") self.reportState("stopped")
else: else:
self.reportState(stateNames[state]) self.reportState(stateNames[state])
if type == lldb.SBProcess.eBroadcastBitStateChanged: if eventType == lldb.SBProcess.eBroadcastBitStateChanged: # 1
state = self.process.GetState() state = self.process.GetState()
if state == lldb.eStateStopped: if state == lldb.eStateStopped:
stoppedThread = self.firstStoppedThread() stoppedThread = self.firstStoppedThread()
@@ -1275,18 +1275,18 @@ class Dumper(DumperBase):
self.reportThreads() self.reportThreads()
self.reportLocation() self.reportLocation()
self.reportChangedBreakpoints() self.reportChangedBreakpoints()
elif type == lldb.SBProcess.eBroadcastBitInterrupt: elif eventType == lldb.SBProcess.eBroadcastBitInterrupt: # 2
pass pass
elif type == lldb.SBProcess.eBroadcastBitSTDOUT: elif eventType == lldb.SBProcess.eBroadcastBitSTDOUT:
# FIXME: Size? # FIXME: Size?
msg = self.process.GetSTDOUT(1024) msg = self.process.GetSTDOUT(1024)
self.report('output={channel="stdout",data="%s"}' self.report('output={channel="stdout",data="%s"}'
% self.hexencode(msg)) % self.hexencode(msg))
elif type == lldb.SBProcess.eBroadcastBitSTDERR: elif eventType == lldb.SBProcess.eBroadcastBitSTDERR:
msg = self.process.GetSTDERR(1024) msg = self.process.GetSTDERR(1024)
self.report('output={channel="stderr",data="%s"}' self.report('output={channel="stderr",data="%s"}'
% self.hexencode(msg)) % self.hexencode(msg))
elif type == lldb.SBProcess.eBroadcastBitProfileData: elif eventType == lldb.SBProcess.eBroadcastBitProfileData:
pass pass
def reportState(self, state): def reportState(self, state):
@@ -1739,43 +1739,88 @@ def doit():
# Used in dumper auto test. # Used in dumper auto test.
# Usage: python lldbbridge.py /path/to/testbinary comma-separated-inames # Usage: python lldbbridge.py /path/to/testbinary comma-separated-inames
def testit(): class Tester(Dumper):
def __init__(self):
Dumper.__init__(self)
lldb.theDumper = self
db = Dumper() self.expandedINames = set(sys.argv[3].split(','))
self.passExceptions = True
self.importDumpers()
error = lldb.SBError()
self.target = self.debugger.CreateTarget(sys.argv[2],
None, None, True, error)
if error.GetType():
warn("ERROR: %s" % error)
return
s = threading.Thread(target=self.testLoop, args=[])
s.start()
def testLoop(self):
# Disable intermediate reporting. # Disable intermediate reporting.
savedReport = db.report savedReport = self.report
db.report = lambda stuff: 0 self.report = lambda stuff: 0
db.debugger.SetAsync(False) ignoreStops = 1
db.expandedINames = set(sys.argv[3].split(',')) if sys.platform == "darwin":
db.passExceptions = True ignoreStops = 0
db.setupInferior({'cmd':'setupInferior','executable':sys.argv[2],'token':1})
error = lldb.SBError()
launchInfo = lldb.SBLaunchInfo([]) launchInfo = lldb.SBLaunchInfo([])
launchInfo.SetWorkingDirectory(os.getcwd()) launchInfo.SetWorkingDirectory(os.getcwd())
environmentList = [key + "=" + value for key,value in os.environ.items()] environmentList = [key + "=" + value for key,value in os.environ.items()]
launchInfo.SetEnvironmentEntries(environmentList, False) launchInfo.SetEnvironmentEntries(environmentList, False)
error = lldb.SBError() self.process = self.target.Launch(launchInfo, error)
db.process = db.target.Launch(launchInfo, error) if error.GetType():
warn("ERROR: %s" % error)
stoppedThread = db.firstStoppedThread() event = lldb.SBEvent()
if stoppedThread: listener = self.debugger.GetListener()
db.process.SetSelectedThread(stoppedThread) while True:
state = self.process.GetState()
if listener.WaitForEvent(100, event):
#warn("EVENT: %s" % event)
out = lldb.SBStream()
event.GetDescription(out)
msg = lldb.SBEvent.GetCStringFromEvent(event)
flavor = event.GetDataFlavor()
state = lldb.SBProcess.GetStateFromEvent(event)
#warn('event={type="%s",data="%s",msg="%s",flavor="%s",state="%s"}'
# % (event.GetType(), out.GetData(), msg, flavor, state))
state = lldb.SBProcess.GetStateFromEvent(event)
if state == lldb.eStateExited:
break
if state == lldb.eStateStopped:
if ignoreStops == 0:
break
ignoreStops -= 1
else:
warn('TIMEOUT')
stoppedThread = self.firstStoppedThread()
if not stoppedThread:
warn("Cannot determined stopped thread")
return
# This seems highly fragile and depending on the "No-ops" in the
# event handling above.
self.process.SetSelectedThread(stoppedThread)
self.report = savedReport
self.reportVariables()
self.report("@NS@%s@" % self.qtNamespace())
#self.report("ENV=%s" % os.environ.items())
#self.report("DUMPER=%s" % self.qqDumpers)
lldb.SBDebugger.Destroy(self.debugger)
db.report = savedReport
ns = db.qtNamespace()
db.reportVariables()
db.report("@NS@%s@" % ns)
#db.report("ENV=%s" % os.environ.items())
#db.report("DUMPER=%s" % db.qqDumpers)
lldb.SBDebugger.Destroy(db.debugger)
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) > 2: if len(sys.argv) > 2:
testit() Tester()
else: else:
doit() doit()

View File

@@ -1104,9 +1104,18 @@ void tst_Dumpers::dumper()
"\n#define BREAK int *nullPtr = 0; *nullPtr = 0;" "\n#define BREAK int *nullPtr = 0; *nullPtr = 0;"
"\n\nvoid unused(const void *first,...) { (void) first; }" "\n\nvoid unused(const void *first,...) { (void) first; }"
"\n#else" "\n#else"
"\n#include <stdint.h>\n" "\n#include <stdint.h>\n";
"\n#define BREAK do { asm(\"int $3\"); } while (0)"
"\n" if (m_debuggerEngine == LldbEngine)
//#ifdef Q_OS_MAC
// fullCode += "\n#define BREAK do { asm(\"int $3\"); } while (0)";
//#else
fullCode += "\n#define BREAK int *nullPtr = 0; *nullPtr = 0;";
//#endif
else
fullCode += "\n#define BREAK do { asm(\"int $3\"); } while (0)";
fullCode += "\n"
"\nstatic volatile int64_t unused_dummy;\n" "\nstatic volatile int64_t unused_dummy;\n"
"\nvoid __attribute__((optimize(\"O0\"))) unused(const void *first,...)\n" "\nvoid __attribute__((optimize(\"O0\"))) unused(const void *first,...)\n"
"\n{\n" "\n{\n"
@@ -1254,7 +1263,7 @@ void tst_Dumpers::dumper()
<< QString::fromUtf8(m_debuggerBinary) << QString::fromUtf8(m_debuggerBinary)
<< t->buildPath + QLatin1String("/doit") << t->buildPath + QLatin1String("/doit")
<< QString::fromUtf8(expanded); << QString::fromUtf8(expanded);
//qDebug() << exe.constData() << ' ' << qPrintable(args.join(QLatin1String(" "))); qDebug() << exe.constData() << ' ' << qPrintable(args.join(QLatin1String(" ")));
} }
t->input = cmds; t->input = cmds;
@@ -2980,7 +2989,7 @@ void tst_Dumpers::dumper_data()
"QString str2(\"Hello\\nQt\");\n" "QString str2(\"Hello\\nQt\");\n"
"QString str3(\"Hello\\rQt\");\n" "QString str3(\"Hello\\rQt\");\n"
"QString str4(\"Hello\\tQt\");\n" "QString str4(\"Hello\\tQt\");\n"
"unused(&str1, &str2, &str3, &str3);\n") "unused(&str1, &str2, &str3, &str4);\n")
+ CoreProfile() + CoreProfile()