PDA

View Full Version : Qt server application Segmentation fault



Qiieha
3rd April 2012, 16:11
Hi
I developed a server application on ubuntu. On Ubuntu the application runs fantastic, but if i try to run the application on
a debian server, the application crash if a client connects. The errror is Segmentation fault.
The libraries are the same on both systems(4.7.4). I despair of the problem. What can be the solution? Or what can cause such an error.

wysota
3rd April 2012, 16:42
Please provide a debugger backtrace from the crash.

Qiieha
3rd April 2012, 16:47
strace:


futex(0x7fc990cd8e40, FUTEX_WAIT_PRIVATE, 2, NULL) = -1 EAGAIN (Resource temporarily unavailable)
futex(0x7fc990cd8e40, FUTEX_WAKE_PRIVATE, 1) = 0
accept(7, 0, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=3, events=POLLIN}, {fd=7, events=POLLIN}, {fd=8, events=POLLIN}], 3, 0) = 1 ([{fd=8, revents=POLLIN}])
ioctl(8, FIONREAD, [210]) = 0
read(8, "\26\3\1\0\315\1\0\0\311\3\1O{\rO\316\277\337P\332\ 300\357\310\275\212LF!\t~\"6"..., 4306) = 210
brk(0xbe8000) = 0xbe8000
futex(0x7fc990cd8e40, FUTEX_WAKE_PRIVATE, 1) = 1
poll([{fd=3, events=POLLIN}, {fd=7, events=POLLIN}, {fd=8, events=POLLIN}, {fd=8, events=POLLOUT}], 4, 0) = 1 ([{fd=8, revents=POLLOUT}])
rt_sigaction(SIGPIPE, {SIG_IGN, [], SA_RESTORER, 0x7fc991497ff0}, NULL, 8) = 0
write(8, "\26\3\1\0005\2\0\0001\3\1O{\f\v;\316\231\355T\217G \1\f\276\217UL\3108h\\"..., 1462) = 1462
poll([{fd=3, events=POLLIN}, {fd=7, events=POLLIN}, {fd=8, events=POLLIN}], 3, 3599997"
) = 1 ([{fd=8, revents=POLLIN}])
ioctl(8, FIONREAD, [2490]) = 0
read(8, "\26\3\1\5d\v\0\5`\0\5]\0\5Z0\202\5V0\202\3>\2\1\0010\r\6\t*\206"..., 6586) = 2490
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
Speicherzugriffsfehler


valgrind


==8559== Process terminating with default action of signal 11 (SIGSEGV)
==8559== Access not within mapped region at address 0xE6A883D4
==8559== at 0xAB5A79E: BN_set_word (in /usr/lib/oracle/10.2.0.4/client64/lib/libnnz10.so)
==8559== by 0xAB59E54: BN_mod_inverse (in /usr/lib/oracle/10.2.0.4/client64/lib/libnnz10.so)
==8559== by 0x7E82A42: BN_BLINDING_create_param (in /usr/lib/libcrypto.so.0.9.8)
==8559== by 0x7E9C850: RSA_setup_blinding (in /usr/lib/libcrypto.so.0.9.8)
==8559== by 0x7E9AC33: ??? (in /usr/lib/libcrypto.so.0.9.8)
==8559== by 0x7E9B087: ??? (in /usr/lib/libcrypto.so.0.9.8)
==8559== by 0x8198790: ssl3_get_client_key_exchange (in /usr/lib/libssl.so.0.9.8)
==8559== by 0x819ADE9: ssl3_accept (in /usr/lib/libssl.so.0.9.8)
==8559== by 0x53A83DC: ??? (in /usr/lib/libQtNetwork.so.4.7.4)
==8559== by 0x53A9B1B: ??? (in /usr/lib/libQtNetwork.so.4.7.4)
==8559== by 0x53A4178: QSslSocket::qt_metacall(QMetaObject::Call, int, void**) (in /usr/lib/libQtNetwork.so.4.7.4)
==8559== by 0x49497E: sslConnection::qt_metacall(QMetaObject::Call, int, void**) (moc_sslconnection.cpp:64)

There is no backtrace. This I get with strace or with valgrind....

wysota
3rd April 2012, 17:06
So run under gdb and get a backtrace.

Qiieha
3rd April 2012, 17:14
ok, thank u for your help ; )
the output of gdb is:


Program received signal SIGSEGV, Segmentation fault.
0x00007ffff334e79e in ?? () from /usr/lib/oracle/10.2.0.4/client64/lib/libnnz10.so


So the lib libnnz10.so is corrupt?

wysota
3rd April 2012, 17:18
Argh... get a backtrace from gdb! type in "bt" and press enter.

Qiieha
3rd April 2012, 17:21
bt:


#0 0x00007ffff334e79e in ?? () from /usr/lib/oracle/10.2.0.4/client64/lib/libnnz10.so
#1 0x00007ffff334de55 in ?? () from /usr/lib/oracle/10.2.0.4/client64/lib/libnnz10.so
#2 0x00007ffff4f33a43 in BN_BLINDING_create_param () from /usr/lib/libcrypto.so.0.9.8
#3 0x00007ffff4f4d851 in RSA_setup_blinding () from /usr/lib/libcrypto.so.0.9.8
#4 0x00007ffff4f4bc34 in ?? () from /usr/lib/libcrypto.so.0.9.8
#5 0x00007ffff4f4c088 in ?? () from /usr/lib/libcrypto.so.0.9.8
#6 0x00007ffff4c53791 in ssl3_get_client_key_exchange () from /usr/lib/libssl.so.0.9.8
#7 0x00007ffff4c55dea in ssl3_accept () from /usr/lib/libssl.so.0.9.8
#8 0x00007ffff76ec3dd in ?? () from /usr/lib/libQtNetwork.so.4
#9 0x00007ffff76edb1c in ?? () from /usr/lib/libQtNetwork.so.4
#10 0x00007ffff76e8179 in QSslSocket::qt_metacall(QMetaObject::Call, int, void**) () from /usr/lib/libQtNetwork.so.4
#11 0x000000000049497f in sslConnection::qt_metacall (this=0x6e0a30, _c=QMetaObject::InvokeMetaMethod, _id=39, _a=0x7fffffffe200) at moc_sslconnection.cpp:64
#12 0x00007ffff72c9f88 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/libQtCore.so.4
#13 0x00007ffff76c9c08 in ?? () from /usr/lib/libQtNetwork.so.4
#14 0x00007ffff76b9681 in ?? () from /usr/lib/libQtNetwork.so.4
#15 0x00007ffff72b41ef in QCoreApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQtCore.so.4
#16 0x00007ffff72b426e in QCoreApplication::notify(QObject*, QEvent*) () from /usr/lib/libQtCore.so.4
#17 0x00007ffff72b3dc4 in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/libQtCore.so.4
#18 0x00007ffff72e188a in ?? () from /usr/lib/libQtCore.so.4
#19 0x00007ffff593a6f2 in g_main_context_dispatch () from /lib/libglib-2.0.so.0
#20 0x00007ffff593e568 in ?? () from /lib/libglib-2.0.so.0
#21 0x00007ffff593e71c in g_main_context_iteration () from /lib/libglib-2.0.so.0
#22 0x00007ffff72e1a1c in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQtCore.so.4
#23 0x00007ffff72b3115 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQtCore.so.4
#24 0x00007ffff72b3366 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQtCore.so.4
#25 0x00007ffff72b51a4 in QCoreApplication::exec() () from /usr/lib/libQtCore.so.4
#26 0x00000000004071f3 in DunningServer::exec (this=0x7fffffffe650) at ../jetdunningprocess_srv/src/dunningserver.cpp:34
#27 0x0000000000406a77 in main (argc=1, argv=0x7fffffffe768) at ../jetdunningprocess_srv/src/main.cpp:8

Qiieha
3rd April 2012, 20:28
Do you think, I should try a newer oracle instant client.

wysota
3rd April 2012, 22:19
Show us your sslConnection class and your DunningServer class.

Qiieha
3rd April 2012, 23:05
DunningServer


#include <QTime>
#include <QDateTime>

#include "dunningserver.h"

int DunningServer::MAXCONN;

DunningServer::DunningServer(int argc, char *argv[]) :
QCoreApplication(argc,argv)
{
qDebug() << "DunningServer::DunningServer(int argc, char *argv[])";
QString max_conn = argv[1];
MAXCONN = max_conn.toInt();
QTime time = QTime::currentTime();
qsrand((uint)time.msec());
connections = QMap<QString,ConnectionHandler*>();
}

int DunningServer::exec() {
qDebug() << "Try to start DunningServer...";

sslServer = new SslServer();
if (!sslServer->listen(QHostAddress::Any,PORT)) {
qDebug() << "...Failed to start server:" << sslServer->errorString();
return -1;
}

Config& config = Config::getInstance();
connect(sslServer,SIGNAL(newConnection()), this, SLOT(acceptConnection()));
qDebug() << "Listening on Port:"<< sslServer->serverPort();

return QCoreApplication::exec();
}

void DunningServer::acceptConnection()
{
qDebug() << "acceptConnection";
QSslSocket* insoc = sslServer->getClientConnection();
qDebug() << "New connection received from "<< insoc->peerAddress().toString();

QString identification = QDateTime::currentDateTime().toString("yyyyMMddhhmmss") + generateRandomString();

ConnectionHandler* new_connection = new ConnectionHandler(insoc,this,identification);
}

void DunningServer::connectionAccepted(ConnectionHandle r* con)
{
qDebug() << "connectionAccepted(ConnectionHandler* con)";
connections.insert(con->getId(),con);
}

void DunningServer::clientDisconnects(QString id)
{
qDebug() << "FsServer::clientDisConnects() called";
ConnectionHandler* connection = connections.value(id);
connections.remove(id);
delete connection;
}

QString DunningServer::generateRandomString()
{
qDebug() << "generateRandomString()";
QString alphabet;
int diff = 'Z'-'A';

for(int i = 0; i < 10; i++){
char c = 'A'+(rand() % diff);
alphabet += QChar(c);
alphabet.append(QString::number(randInt(0,10)));
}
return alphabet;
}

int DunningServer::randInt(int low, int high)
{
qDebug() << "randInt";
return qrand() % ((high + 1) - low) + low;
}


sslconnection.h


#ifndef SSLCONNECTION_H
#define SSLCONNECTION_H

#include <QSslSocket>
#include <QSslKey>
#include <QSslConfiguration>

class sslConnection: public QSslSocket
{
Q_OBJECT
public:
sslConnection( int socketDescriptor, QObject *parent );
};

#endif // SSLCONNECTION_H


sslconnection.cpp


#include <QNoDebug>
#include "sslconnection.h"

sslConnection::sslConnection( int socketDescriptor, QObject *parent ) : QSslSocket( parent )
{
qDebug() << "sslConnection";
if( !setSocketDescriptor( socketDescriptor ) )
{
deleteLater();
return;
}

setProtocol(QSsl::TlsV1);
setPeerVerifyMode(QSslSocket::VerifyPeer);

addCaCertificates(QSslCertificate::fromPath("server.crt"));
QByteArray passphrase("passphrase");
setLocalCertificate("server.crt");
setPrivateKey("server.key",QSsl::Rsa,QSsl::Pem,passphrase);

QSslError error(QSslError::SelfSignedCertificate);
QSslError error1(QSslError::CertificateUntrusted);
QSslError error2(QSslError::HostNameMismatch);
QList<QSslError> expectedSslErrors;
expectedSslErrors.append(error);
expectedSslErrors.append(error1);
expectedSslErrors.append(error2);
ignoreSslErrors(expectedSslErrors);
startServerEncryption();
}

wysota
3rd April 2012, 23:11
Does it change anything if you comment out lines #13 and #14 from sslConnection?

Qiieha
3rd April 2012, 23:18
I cannot test it today. I'll do it tomorrow. But I think the handshake won't be successfull

wysota
3rd April 2012, 23:24
By the way, do you have multiple threads in your application?

Qiieha
4th April 2012, 09:05
Yes there is one Thread to get time-consuming data. In the run method a new DataBase Connection is established and the data is queried. After finishing the thread gives over the data by signal and slot to the main thread. You think this could be the problem? I could imagine it, but why? And why it runs on my local machine?



Does it change anything if you comment out lines #13 and #14 from sslConnection?


The program doesn't crash, but the handshake is not successful.

wysota
4th April 2012, 09:29
Yes there is one Thread to get time-consuming data. In the run method a new DataBase Connection is established and the data is queried. After finishing the thread gives over the data by signal and slot to the main thread. You think this could be the problem? I could imagine it, but why? And why it runs on my local machine?
It could be as the backtrace strangely jumps from establishing an SSL connection to the database driver. Can we see the code of the thread?


The program doesn't crash, but the handshake is not successful.
Try commenting out only one of the two lines. Do you have standard OpenSSL libraries on the target system?

Qiieha
4th April 2012, 09:44
thread:


#include <QDebug>
#include <QSqlQuery>
#include <QSqlError>
#include <QVariant>
#include <QSqlDatabase>
#include <QSqlRecord>
#include <QDateTime>

#include "recsthread.h"

RecsThread::RecsThread(QObject *parent, QList<DataSet *> *datasets) :
QThread(parent),
datasets(datasets)
{
db_name = generateRandomString() + QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
}

RecsThread::~RecsThread()
{
qDebug() << "~RecsThread";
QSqlDatabase::database(db_name).close();
QSqlDatabase::removeDatabase(db_name);
}

void RecsThread::run()
{
QSqlDatabase temp_db = QSqlDatabase::addDatabase("QOCI8",db_name);
temp_db.setHostName("hostname");
temp_db.setDatabaseName("database1");
temp_db.setUserName( "user1" );
temp_db.setPassword( "passwd" );
temp_db.open();

QMap<int,IndependentlyMap<Record*>*>* records = new QMap<int,IndependentlyMap<Record*>*>();
QSqlQuery query(temp_db);
//query.exec();
//fill records with data

emit recs_here(records);
}

int RecsThread::randInt(int low, int high)
{
return qrand() % ((high + 1) - low) + low;
}

QString RecsThread::generateRandomString()
{
QString alphabet;
int diff = 'Z'-'A';

for(int i=0;i<10;i++){
char c = 'A'+(rand() % diff);
alphabet += QChar(c);
alphabet.append(QString::number(randInt(0,10)));
}
return alphabet;
}



Try commenting out only one of the two lines. Do you have standard OpenSSL libraries on the target system?

if I comment the second of the two lines, the segmentation fault appers and if I comment the first of the two line, the handshake is not successfull.

wysota
4th April 2012, 09:49
It seems as if your OpenSSL implementation was somehow broken and couldn't handle the TLS handshake.

Qiieha
4th April 2012, 10:54
It could be as the backtrace strangely jumps from establishing an SSL connection to the database driver. Can we see the code of the thread?

I found the bug and worked arround it. I started the thread prior to establish my sslconnecion. So wysota was rigth. There was something wrong with my ssl libs and oci libs. Now i it works.