forked from qt-creator/qt-creator
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:
@@ -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()
|
||||||
|
|
||||||
|
@@ -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()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user