forked from qt-creator/qt-creator
Android: Warn about broken gdbs on every platform
Add more indicators for a broken gdb. This also fixes a bug where the message was errounously shown on non-OS X platforms Task-number: QTCREATORBUG-12747 Change-Id: I7936e5eea58896aec382616d6e7236b8276f998d Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -136,6 +136,9 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
|
|||||||
{
|
{
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
|
connect(&m_checkGdbWatcher, SIGNAL(finished()),
|
||||||
|
this, SLOT(checkGdbFinished()));
|
||||||
|
|
||||||
m_ui->SDKLocationPathChooser->setFileName(m_androidConfig.sdkLocation());
|
m_ui->SDKLocationPathChooser->setFileName(m_androidConfig.sdkLocation());
|
||||||
m_ui->SDKLocationPathChooser->setPromptDialogTitle(tr("Select Android SDK folder"));
|
m_ui->SDKLocationPathChooser->setPromptDialogTitle(tr("Select Android SDK folder"));
|
||||||
m_ui->NDKLocationPathChooser->setFileName(m_androidConfig.ndkLocation());
|
m_ui->NDKLocationPathChooser->setFileName(m_androidConfig.ndkLocation());
|
||||||
@@ -180,8 +183,6 @@ AndroidSettingsWidget::AndroidSettingsWidget(QWidget *parent)
|
|||||||
|
|
||||||
connect(&m_futureWatcher, SIGNAL(finished()),
|
connect(&m_futureWatcher, SIGNAL(finished()),
|
||||||
this, SLOT(avdAdded()));
|
this, SLOT(avdAdded()));
|
||||||
connect(&m_checkGdbWatcher, SIGNAL(finished()),
|
|
||||||
this, SLOT(checkGdbFinished()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidSettingsWidget::~AndroidSettingsWidget()
|
AndroidSettingsWidget::~AndroidSettingsWidget()
|
||||||
@@ -191,38 +192,47 @@ AndroidSettingsWidget::~AndroidSettingsWidget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Will be run via QFuture
|
// NOTE: Will be run via QFuture
|
||||||
static QPair<QString, bool> checkGdbForBrokenPython(const QString &path)
|
static QPair<QStringList, bool> checkGdbForBrokenPython(const QStringList &paths)
|
||||||
{
|
{
|
||||||
QTime timer;
|
foreach (const QString &path, paths) {
|
||||||
timer.start();
|
QTime timer;
|
||||||
QProcess proc;
|
timer.start();
|
||||||
proc.setProcessChannelMode(QProcess::MergedChannels);
|
QProcess proc;
|
||||||
proc.start(path);
|
proc.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
proc.waitForStarted();
|
proc.start(path);
|
||||||
|
proc.waitForStarted();
|
||||||
|
|
||||||
QByteArray output;
|
QByteArray output;
|
||||||
while (proc.waitForReadyRead(300)) {
|
while (proc.waitForReadyRead(300)) {
|
||||||
output += proc.readAll();
|
output += proc.readAll();
|
||||||
if (output.contains("(gdb)"))
|
if (output.contains("(gdb)"))
|
||||||
break;
|
break;
|
||||||
if (timer.elapsed() > 7 * 1000)
|
if (timer.elapsed() > 7 * 1000)
|
||||||
return qMakePair(path, false); // Took too long, abort
|
return qMakePair(path, true); // Took too long, abort
|
||||||
|
}
|
||||||
|
|
||||||
|
output.clear();
|
||||||
|
|
||||||
|
proc.write("python import string\n");
|
||||||
|
proc.write("python print(string.ascii_uppercase)\n");
|
||||||
|
proc.write("python import struct\n");
|
||||||
|
proc.write("quit\n");
|
||||||
|
while (proc.waitForFinished(300)) {
|
||||||
|
if (timer.elapsed() > 9 * 1000)
|
||||||
|
return qMakePair(path, true); // Took too long, abort
|
||||||
|
}
|
||||||
|
proc.waitForFinished();
|
||||||
|
|
||||||
|
output = proc.readAll();
|
||||||
|
|
||||||
|
bool error = output.contains("_PyObject_Free")
|
||||||
|
|| output.contains("_PyExc_IOError")
|
||||||
|
|| output.contains("_sysconfigdata_nd ")
|
||||||
|
|| !output.contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||||
|
if (error)
|
||||||
|
return qMakePair(paths, error);
|
||||||
}
|
}
|
||||||
|
return qMakePair(paths, false);
|
||||||
output.clear();
|
|
||||||
|
|
||||||
proc.write("python import struct\n");
|
|
||||||
proc.write("quit\n");
|
|
||||||
while (proc.waitForFinished(300)) {
|
|
||||||
if (timer.elapsed() > 9 * 1000)
|
|
||||||
return qMakePair(path, false); // Took too long, abort
|
|
||||||
}
|
|
||||||
proc.waitForFinished();
|
|
||||||
|
|
||||||
output = proc.readAll();
|
|
||||||
|
|
||||||
bool error = output.contains("_PyObject_Free") || output.contains("_PyExc_IOError");
|
|
||||||
return qMakePair(path, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
|
void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
|
||||||
@@ -240,6 +250,8 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
|
|||||||
Utils::FileName platformPath = m_androidConfig.ndkLocation();
|
Utils::FileName platformPath = m_androidConfig.ndkLocation();
|
||||||
Utils::FileName toolChainPath = m_androidConfig.ndkLocation();
|
Utils::FileName toolChainPath = m_androidConfig.ndkLocation();
|
||||||
Utils::FileName sourcesPath = m_androidConfig.ndkLocation();
|
Utils::FileName sourcesPath = m_androidConfig.ndkLocation();
|
||||||
|
m_ui->gdbWarningIconLabel->setVisible(false);
|
||||||
|
m_ui->gdbWarningLabel->setVisible(false);
|
||||||
if (m_androidConfig.ndkLocation().isEmpty()) {
|
if (m_androidConfig.ndkLocation().isEmpty()) {
|
||||||
m_ndkState = NotSet;
|
m_ndkState = NotSet;
|
||||||
} else if (!platformPath.appendPath(QLatin1String("platforms")).toFileInfo().exists()
|
} else if (!platformPath.appendPath(QLatin1String("platforms")).toFileInfo().exists()
|
||||||
@@ -257,22 +269,20 @@ void AndroidSettingsWidget::check(AndroidSettingsWidget::Mode mode)
|
|||||||
m_ndkCompilerCount = compilerPaths.count();
|
m_ndkCompilerCount = compilerPaths.count();
|
||||||
|
|
||||||
// Check for a gdb with a broken python
|
// Check for a gdb with a broken python
|
||||||
if (Utils::HostOsInfo::isMacHost()) {
|
QStringList gdbPaths;
|
||||||
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) {
|
foreach (const AndroidToolChainFactory::AndroidToolChainInformation &ati, compilerPaths) {
|
||||||
// we only check the arm gdbs, that's indicative enough
|
// we only check the arm gdbs, that's indicative enough
|
||||||
if (ati.architecture != ProjectExplorer::Abi::ArmArchitecture)
|
if (ati.architecture != ProjectExplorer::Abi::ArmArchitecture)
|
||||||
continue;
|
continue;
|
||||||
Utils::FileName gdbPath = AndroidConfigurations::currentConfig().gdbPath(ati.architecture, ati.version);
|
Utils::FileName gdbPath = m_androidConfig.gdbPath(ati.architecture, ati.version);
|
||||||
if (gdbPath.toFileInfo().exists()) {
|
if (gdbPath.toFileInfo().exists())
|
||||||
m_ui->gdbWarningIconLabel->setVisible(false);
|
gdbPaths << gdbPath.toString();
|
||||||
m_ui->gdbWarningLabel->setVisible(false);
|
|
||||||
m_checkGdbWatcher.setFuture(QtConcurrent::run(&checkGdbForBrokenPython, gdbPath.toString()));
|
|
||||||
m_gdbCheckPath = gdbPath.toString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gdbPaths.isEmpty()) {
|
||||||
|
m_checkGdbWatcher.setFuture(QtConcurrent::run(&checkGdbForBrokenPython, gdbPaths));
|
||||||
|
m_gdbCheckPaths = gdbPaths;
|
||||||
|
}
|
||||||
|
|
||||||
// See if we have qt versions for those toolchains
|
// See if we have qt versions for those toolchains
|
||||||
QSet<ProjectExplorer::Abi::Architecture> toolchainsForArch;
|
QSet<ProjectExplorer::Abi::Architecture> toolchainsForArch;
|
||||||
@@ -569,8 +579,8 @@ void AndroidSettingsWidget::createKitToggled()
|
|||||||
|
|
||||||
void AndroidSettingsWidget::checkGdbFinished()
|
void AndroidSettingsWidget::checkGdbFinished()
|
||||||
{
|
{
|
||||||
QPair<QString, bool> result = m_checkGdbWatcher.future().result();
|
QPair<QStringList, bool> result = m_checkGdbWatcher.future().result();
|
||||||
if (result.first != m_gdbCheckPath) // no longer relevant
|
if (result.first != m_gdbCheckPaths) // no longer relevant
|
||||||
return;
|
return;
|
||||||
m_ui->gdbWarningIconLabel->setVisible(result.second);
|
m_ui->gdbWarningIconLabel->setVisible(result.second);
|
||||||
m_ui->gdbWarningLabel->setVisible(result.second);
|
m_ui->gdbWarningLabel->setVisible(result.second);
|
||||||
|
|||||||
@@ -114,8 +114,8 @@ private:
|
|||||||
AndroidConfig m_androidConfig;
|
AndroidConfig m_androidConfig;
|
||||||
AvdModel m_AVDModel;
|
AvdModel m_AVDModel;
|
||||||
QFutureWatcher<AndroidConfig::CreateAvdInfo> m_futureWatcher;
|
QFutureWatcher<AndroidConfig::CreateAvdInfo> m_futureWatcher;
|
||||||
QFutureWatcher<QPair<QString, bool>> m_checkGdbWatcher;
|
QFutureWatcher<QPair<QStringList, bool>> m_checkGdbWatcher;
|
||||||
QString m_gdbCheckPath;
|
QStringList m_gdbCheckPaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
Reference in New Issue
Block a user