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:
Daniel Teske
2014-07-29 13:32:24 +02:00
parent 3f4e966664
commit 677746cd82
2 changed files with 59 additions and 49 deletions

View File

@@ -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,8 +192,9 @@ 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)
{ {
foreach (const QString &path, paths) {
QTime timer; QTime timer;
timer.start(); timer.start();
QProcess proc; QProcess proc;
@@ -206,23 +208,31 @@ static QPair<QString, bool> checkGdbForBrokenPython(const QString &path)
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(); output.clear();
proc.write("python import string\n");
proc.write("python print(string.ascii_uppercase)\n");
proc.write("python import struct\n"); proc.write("python import struct\n");
proc.write("quit\n"); proc.write("quit\n");
while (proc.waitForFinished(300)) { while (proc.waitForFinished(300)) {
if (timer.elapsed() > 9 * 1000) if (timer.elapsed() > 9 * 1000)
return qMakePair(path, false); // Took too long, abort return qMakePair(path, true); // Took too long, abort
} }
proc.waitForFinished(); proc.waitForFinished();
output = proc.readAll(); output = proc.readAll();
bool error = output.contains("_PyObject_Free") || output.contains("_PyExc_IOError"); bool error = output.contains("_PyObject_Free")
return qMakePair(path, error); || output.contains("_PyExc_IOError")
|| output.contains("_sysconfigdata_nd ")
|| !output.contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
if (error)
return qMakePair(paths, error);
}
return qMakePair(paths, false);
} }
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);

View File

@@ -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