コンテキスト: 私はそのようなファイルのセットを持っています:
alias
USER = usr_name
PASSWORD = pass
...
alias2
...
qtableviewに表示するファイルを選択するコンボボックスがあります。以下は、コンボボックスの値が変更されたときに呼び出されるスロットです。
void paramTableModel::switchTable(QString env)
{
// is there an environment defined
// --------------------------------------
if(env.compare("") != 0)
{
// does the param file exist ?
// ---------------------------
QString file_path = "/path/to/" + env + "/path/to/file;
QFile param_file(file_path);
if( param_file.exists() && param_file.open(QIODevice::ReadOnly))
{
QString program_decrypt = "/path/to/decrypt";
QStringList args;
args << file_path;
QProcess* process = new QProcess();
process->setReadChannel(QProcess::StandardOutput);
process->start(program_decrypt,args);
process->waitForFinished(-1);
QTextStream in(&process->readAll());
//start resetting model (notify the view )
beginResetModel();
this->table.clear();
std::set<QString> uniq;
// parse file to model
// -------------------
while( !in.atEnd() )
{
QString line = in.readLine();
// some new UT ?
// -------------------
if( !line.isNull() && line.trimmed().compare("") != 0 && !line.contains("="))
{
line = line.trimmed();
std::vector<QString> row;
if(uniq.find(line) == uniq.end())
{
uniq.insert(line);
row.push_back(line);
QString user_line = in.readLine().trimmed();
QString password_line = in.readLine().trimmed();
QString server_line = in.readLine().trimmed();
if( user_line.startsWith("USER") )
{
user_line = user_line.split('=').at(1).trimmed();
}
if( password_line.startsWith("PASSWORD") )
{
password_line = password_line.split('=').at(1).trimmed();
}
if( server_line.startsWith("SERVER") )
{
server_line = server_line.split('=').at(1).trimmed();
}
row.push_back(user_line);
row.push_back(password_line);
row.push_back(server_line);
this->table.push_back(row);
}
else
{
QMessageBox msgBox;
msgBox.setText(QString("%1 is already defined, ingnoring").arg(line));
msgBox.exec();
}
}
}
param_file.close();
endResetModel();
delete process;
}
}
}
ほとんどの場合、ビューは適切に更新されます。そして時々、この行はセグメンテーション違反を起こします:
QString line = in.readLine();
体系的な方法でバグを再現するパターンは見つかりませんでした。コンボボックス内の 2 つのファイル間を行ったり来たりすることができます。10 回、12 回、20 回と segfault が実行されます。
編集:
これは機能します。
void paramTableModel::switchTable(QString env)
{
// is there an environment defined
// --------------------------------------
if(env.isEmpty())
return;
// does the param file exist ?
// --------------------------------
QString file_path = "/path/to/env/" + env + "/path/to/file.dat";
QFile param_file(file_path);
if( param_file.exists() && param_file.open(QIODevice::ReadOnly))
{
// Call QProcess, fx_decrypt, read standard output
QString program_decrypt = "/path/to/decrypt";
QStringList args;
args << file_path;
QProcess process;
process.setReadChannel(QProcess::StandardOutput);
process.start(program_decrypt,args);
process.waitForFinished(-1);
//QTextStream in(&process->readAll());
QString out = process.readAll();
QStringList list_out = out.split("\n",QString::SkipEmptyParts);
//start resetting model (notify the view )
beginResetModel();
this->table.clear();
std::set<QString> uniq;
// parse file to model
// -----------------------
//while( !in.atEnd() )
int counter = 0;
while(counter < list_out.size())
{
//QString line = in.readLine();
QString line = list_out.at(counter);
// some new UT ?
// -------------------
if( !line.isNull() && !line.trimmed().isEmpty() != 0 && !line.contains("="))
{
line = line.trimmed();
std::vector<QString> row;
if(uniq.find(line) == uniq.end())
{
uniq.insert(line);
row.push_back(line);
/**QString user_line = in.readLine().trimmed();
QString password_line = in.readLine().trimmed();
QString server_line = in.readLine().trimmed();*/
QString user_line = list_out.at(++counter).trimmed();
QString password_line = list_out.at(++counter).trimmed();
QString server_line = list_out.at(++counter).trimmed();
if( user_line.startsWith("USER") )
{
user_line = user_line.split('=').at(1).trimmed();
}
if( password_line.startsWith("PASSWORD") )
{
password_line = password_line.split('=').at(1).trimmed();
}
if( server_line.startsWith("SERVER") )
{
server_line = server_line.split('=').at(1).trimmed();
}
row.push_back(user_line);
row.push_back(password_line);
row.push_back(server_line);
this->table.push_back(row);
}
else
{
QMessageBox msgBox;
msgBox.setText(QString("%1 is already defined, ingnoring").arg(line));
msgBox.exec();
}
}
++counter;
}
endResetModel();
}
}
@Kuba Oberの提案に従って、バグの理由を取得しようとしています
すべての環境で無期限にループするメイン関数に最初のバージョンをコピーしようとしました。
しかし、それはうまくいきます!
#include <QtCore/QCoreApplication>
#include <QProcess>
#include <QTextStream>
#include <set>
#include <vector>
#include <QDebug>
#include <QFile>
#include <deque>
#include <QDir>
#include <QStringList>
std::deque< std::vector < QString > > table;
void f( QString file_path )
{
// does the param file exist ?
// --------------------------------
QFile param_file(file_path);
if( param_file.exists() && param_file.open(QIODevice::ReadOnly))
{
// Call QProcess, fx_decrypt, read standard output
QString program_decrypt = "/path/to/decrypt";
QStringList args;
args << file_path;
QProcess* process = new QProcess();
process->setReadChannel(QProcess::StandardOutput);
process->start(program_decrypt,args);
process->waitForFinished(-1);
QTextStream in(&process->readAll());
//start resetting model (notify the view )
table.clear();
std::set<QString> uniq;
// parse file to model
// -----------------------
while( !in.atEnd() )
{
QString line = in.readLine();
// some new UT ?
// -------------------
if( !line.isNull() && line.trimmed().isEmpty() != 0 && !line.contains("="))
{
line = line.trimmed();
std::vector<QString> row;
if(uniq.find(line) == uniq.end())
{
uniq.insert(line);
row.push_back(line);
QString user_line = in.readLine().trimmed();
QString password_line = in.readLine().trimmed();
QString server_line = in.readLine().trimmed();
if( user_line.startsWith("USER") )
{
user_line = user_line.split('=').at(1).trimmed();
}
if( password_line.startsWith("PASSWORD") )
{
password_line = password_line.split('=').at(1).trimmed();
}
if( server_line.startsWith("SERVER") )
{
server_line = server_line.split('=').at(1).trimmed();
}
row.push_back(user_line);
row.push_back(password_line);
row.push_back(server_line);
table.push_back(row);
}
else
{
qDebug() << QString("%1 is already defined, ingnoring").arg(line);
}
}
}
param_file.close();
delete process;
}
}
QStringList getEnvList()
{
QDir dir("/path/to/env/");
QStringList list_env;
foreach(QString folder, dir.entryList(QStringList(),QDir::AllDirs | QDir::NoDotAndDotDot))
{
QFile app_file( dir.absolutePath() + '/' + folder + '/' + "file.dat" );
if (app_file.exists())
{
list_env.push_back(folder);
}
}
return list_env;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int counter = 0;
while(true)
{
foreach ( QString s, getEnvList() )
{
qDebug() << counter++;
qDebug() << s;
f(s);
}
}
return a.exec();
}
最初のコードがクラッシュするのに、以下の2つのコードがクラッシュしない理由はわかりません...