PDA

View Full Version : Program crashes



Fallen_
17th September 2010, 06:05
Hi, when calling this:

std::string final = tmp.substr(tmp.find(" "), tmp.length());
m_chan = new Channel(this, QString(final.c_str()), socket);
tabs->addTab(m_chan, QString(final.c_str()));
the program crahes without a reason. im sure the tmp has a " "
PS:
when i debug i get seg fault

tbscope
17th September 2010, 06:34
Possible problems:

tabs = 0
m_chan = 0
if socket is a pointer, it can be 0 too.

So, do a check on all pointers, or check your backtrace to find which pointer is 0

Fallen_
17th September 2010, 06:42
already did, nothing wrong

tbscope
17th September 2010, 06:43
Post your backtrace.

Fallen_
17th September 2010, 06:56
Did you mean this?:
Signal name: SIGSEGV
Signal meaning: Segmentation fault
if not:
http://pastebin.com/R5uubZPf
---The text that you have entered is too long (46227 characters). Please shorten it to 10000 characters long.
anything else?

tbscope
17th September 2010, 07:02
No, that is the compiled code of a QWidget::setParent function.

But it might get us closer to the error.
If your program fails in this function, you're creating a widget with a non valid parent.

I guess Channel is a widget?
And the first argument in the constructor is the parent?
Does "this" exist?

Fallen_
17th September 2010, 07:04
Channel is a widget yes, and "this" exist while calling it and yes the first arguemnt is QWidget

tbscope
17th September 2010, 07:09
I would love to see the backtrace.

What system are you using? Window, Linux, MacOs, ... ?
What IDE are you using? Qt Creator, ... ?

Fallen_
17th September 2010, 07:11
Windows, Qt creator (to debug), and Qt Command Line to compile. how do i get the backtrace?

tbscope
17th September 2010, 07:21
In Qt Creator, in stead of running the program normally, run the program in the debugger.
When it crashes, go to the stack view (should be the list on the left I think), it should contain the backtrace.

Fallen_
17th September 2010, 07:34
nope, cant see anything :(

tbscope
17th September 2010, 07:41
I'm not in front of my computer at the moment so I can't help you with that at the moment.

But to give some more information:
The backtrace is a list of functions that were the last functions being run in your program.
The very last function in this list usually contains the crash. You can then follow the list of functions to see where the problem first occured.

Segmentation faults happen when you try to access memory that you should never access (like the memory segment of the kernel). Most of the time this happens when the pointer to an object is 0.

The stack list should be the list on the left in the debugging section of Qt Creator.

SixDegrees
17th September 2010, 08:32
I agree that running in a debugger will be the fastest solution here. Another point: you never check the results of your "find" operation. Despite your insistence that there's a space to be found in the string, it's poor form not to check that the operation actually succeeded.

You could also simply print the results of each line shown to cerr, which would at least isolate the line that is causing the problem. Printing out tmp prior to the string manipulations would also shed some light.

Fallen_
17th September 2010, 19:17
ok i have made something like this:

if(sscanf(tmp.c_str(), "/join %s", buffer) > 0) {
and then read->append(buffer) and it worked but i commented out the:

m_chan = new Channel(this, QString(buffer), socket);
tabs->addTab(m_chan, QString(buffer));
so its something wrong with them.

wysota
17th September 2010, 20:18
Is there any specific reason that you are using C strings and std::string instead of QString?

Please show us the constructor of Channel.

Fallen_
17th September 2010, 21:16
Channel::Channel(QWidget* parent, const QString& name, QTcpSocket* socket)
: QWidget(parent), chan(name), m_socket(socket)
{
write = new QLineEdit;
read = new QTextEdit;
send = new QPushButton(tr("Send"));
read->setReadOnly(true);
QVBoxLayout* layout = new QVBoxLayout;
layout->addWidget(read);
layout->addWidget(write);
layout->addWidget(send);
setLayout(layout);
setWindowTitle(name.toLatin1());
connect(send, SIGNAL(clicked()), this, SLOT(sendM()));
read->append("Welcome to " + name + "\n");
}

SixDegrees
17th September 2010, 21:26
buffer is a QString. Print it out and see what it contains before using it.

Or - still by far the best bet - run your code through a debugger and isolate the problem in a minute or two.

wysota
17th September 2010, 21:31
Could you print the value of buffer before calling the constructor?

By the way, if you want to extract the argument to your "/join" command, you can do it this way:


// assuming QString tmp holds the complete line (i.e. "/join #qt")
// detect '/' followed by an alphanumeric string followed by a whitespace followed by some other text
QRegExp commandRx("^/([A-Za-z][A-Za-z0-0]+)\\s(.*)$");
if(commandRx.exactMatch(tmp)){
// we have found a command
QString cmdName = commandRx.cap(1); // command name (first set of brackets)
QString arguments = commandRx.cap(2); // everything past the space (second set of brackets)
cmdName = cmdName.toLower();
if(cmdName == "join") {
QStringList channels = arguments.split(" "); // split on spaces
foreach(QString channel, channels) {
if(channel.startsWith("#")) {
joinChannel(channel.mid(1)); // join everything starting with '#'
}
}
} else if(cmdName == ... ) {
...
} ...
}

Fallen_
17th September 2010, 21:52
man i already made it to get the text, now when i do something like this:

tabs->addTab(new Channel(this, QString(buffer), socket, ""), QString(buffer));
it works but i need it to append a text in the text edit of the channel, when i call printText (from the channel class) from another function it doesnt do anything:

Channel *chan = new Channel(this, channel.c_str(), socket, tmp);
chan->printText(tmp);
any ideas?

wysota
17th September 2010, 22:00
man i already made it to get the text,
I'm aware of it, the point is you are doing it with a C api that is cumbersome and error prone.


it works but i need it to append a text in the text edit of the channel, when i call printText (from the channel class) from another function it doesnt do anything
I have no idea what you mean. What is printText(), what other function and what was it supposed to do?

Fallen_
17th September 2010, 22:10
its to append a text in the "read" text edit

tbscope
18th September 2010, 06:37
If you have still problems with the crash, put your code into a zip file and attach it to your post and I'll see what the problem is.

Fallen_
18th September 2010, 14:37
I'm aware of it, the point is you are doing it with a C api that is cumbersome and error prone.


I have no idea what you mean. What is printText(), what other function and what was it supposed to do?
Well, the printText is a function in the "Channel" class when calling it from the "MainWindow" class it doesnt print text in the "read" textEdit, heres what printText supposed to do:

void Channel::printText(const QString& text)
{
read->append(text);
}

wysota
18th September 2010, 20:34
And how do you call it from MainWindow?

Fallen_
18th September 2010, 21:18
Channel* chan = new Channel(this, channel.c_str(), socket);
chan->printText(tmp);

Zlatomir
18th September 2010, 21:47
I guess that's because you create that C-style string pointer, if you want to create a QString from a std::string don't use the .c_str() method, use the static member function of QString fromStdString() (http://doc.qt.nokia.com/latest/qstring.html#fromStdString) (this create a copy of the string)

It has been said: it's better if you use QString instead std::string (and C-style strings)

wysota
18th September 2010, 22:31
Channel* chan = new Channel(this, channel.c_str(), socket);
chan->printText(tmp);

And the program runs but the text is not printed? What is the content of "tmp" at this moment?

Fallen_
18th September 2010, 22:48
And the program runs but the text is not printed? What is the content of "tmp" at this moment?
tmp is a char array with the received messages from the socket and ye it doesnt print the text.

I guess that's because you create that C-style string pointer, if you want to create a QString from a std::string don't use the .c_str() method, use the static member function of QString fromStdString() (http://doc.qt.nokia.com/latest/qstring.html#fromStdString) (this create a copy of the string)

It has been said: it's better if you use QString instead std::string (and C-style strings)
nope still doesnt work

wysota
18th September 2010, 23:08
tmp is a char array with the received messages from the socket and ye it doesnt print the text.
I'm asking what it contains - literally. Please print it to your console, don't assume you know what's in there.

Fallen_
18th September 2010, 23:46
I'm asking what it contains - literally. Please print it to your console, don't assume you know what's in there.
thats what written in there:

:stockholm.se.quakenet.org 366 Fallen_ #Fallen :End of /NAMES list.

[00:45:51] Fallen_ has joined #Fallen

wysota
18th September 2010, 23:57
And how did you print that to the console?

Fallen_
19th September 2010, 20:20
using qDebug()?

wysota
19th September 2010, 21:04
Show us the statement please. With a couple of surrounding lines.

Fallen_
19th September 2010, 23:05
ive showed u 2 lines already, the problem is not the lines....

wysota
19th September 2010, 23:20
the **** u mean? ive showed u 2 lines already, the problem is not the lines....

The code, not the text.

SixDegrees
19th September 2010, 23:34
ive showed u 2 lines already, the problem is not the lines....

Look - programs are a compendium of statements that operate on data. If you're having a problem, it can only be in one of two places - the statements, or the data those statements operate on.

You've been asked to print out the strings your program makes use of - not just the input strings, but the strings after you've gotten done munging around with them. The strings that you feed to your program statements. If the input data is wrong (and frankly, this seems likely, given that you're attempting to transform between three different string manipulation libraries) then your statements aren't going to produce the results you expect.

So far, in two full pages, you've produced the single, top-level input string, but none of what was actually asked for.

Also, although many people frown upon it, "printf-style" debugging is often a fast, efficient means to find out what's wrong with your program. Yes, a debugger will usually get you there faster. But especially when working with potentially corrupt strings, simply dumping those strings to a console often provides you (or those you're asking to do your work for you) valuable clues about what the problem may actually be.

You've also refused to produce code, despite a number of such requests.

If you can't play along, figure it out for yourself; you've been given far more than enough guidance to do so. If, however, you want others to help you, you're going to have to respond fully and accurately - and politely - when those you're asking for help request additional information.

Fallen_
19th September 2010, 23:53
The code, not the text.

void MainWindow::appendToWindow()
{
char buffer[1024], tmp[1024];
while(socket->canReadLine()) {
socket->readLine(buffer, sizeof(buffer));
std::string str = buffer;
std::string name = getName(buffer), msg = getMsg(buffer), channel = getChannel(buffer), t = getTime();
if(connected) {
if(str.substr(0, 4) == "PING") {
std::string s = "PO" + str.substr(2) + "\r\n";
socket->write(s.c_str());
}
else if(str.find("PRIVMSG") != std::string::npos)
sprintf(tmp, "%s <%s>(%s) %s", t.c_str(), name.c_str(), channel.c_str(), msg.c_str());
else if(str.find("NOTICE") != std::string::npos)
sprintf(tmp, "%s Notice from: %s Message: %s", t.c_str(), name.c_str(), msg.c_str());
else if(str.find("JOIN") != std::string::npos)
sprintf(tmp, "%s %s has joined %s", t.c_str(), name.c_str(), channel.c_str());
else if(str.find("PART") != std::string::npos)
sprintf(tmp, "%s %s has left %s (%s)", t.c_str(), name.c_str(), channel.c_str(), msg.c_str());
else if(str.find("QUIT") != std::string::npos)
sprintf(tmp, "%s %s has quit (%s)", t.c_str(), name.c_str(), msg.c_str());
else
read->append(buffer);

Channel* chan = new Channel(NULL, QString::fromLatin1(channel.c_str()), NULL);
chan->printText(QString::fromLatin1(tmp));
read->append(tmp);
}
}
}

wysota
20th September 2010, 00:02
The code you pasted does not contain the qDebug statement I asked you for...

Fallen_
20th September 2010, 00:08
it had it, but i removed it since its not needed but the lines are 26-28 (read->append(tmp) is the read text edit from the MainWindow so i know that theres still text))

wysota
20th September 2010, 00:25
In that case I have no idea what you want. From what I understood from post #23 you said read->append(tmp) didn't work. So what's the problem exactly? Try to be as specific and clear as you can.

Fallen_
20th September 2010, 00:31
the read->append(tmp in post #37 is for the MainWindow the problem is the read->append in Channel, it doesnt work ;/////

wysota
20th September 2010, 00:42
What is "read" from post #37 and what is "read" from post (the one that doesn't work)? They point to different objects, yes?

Naming your variables in such a vague way is probably not the best programming practice...

Fallen_
20th September 2010, 01:26
#37 works, #25 doesnt :-((((
#37 point to MainWindow, #25 points to Channel.

wysota
20th September 2010, 01:32
Is English your primary language? Do you have problems understanding what I write? If I'm not clear enough, please say what needs clarification as so far you have misunderstood what I said a couple of times. I'm asking you what your "read" variables contain in both cases (MainWindow and Channel classes).

Fallen_
20th September 2010, 01:40
because ur asking too many weird questions... whats it all about is:
1. i made the channel class which inherits QWidget
2. i open up a tab when basically the user requests to join a channel basically like this:

tabs->addTab(new Channel(this, QString::fromLatin1(buffer), socket), QString::fromLatin1(buffer));
3. the "read QTextEdit is in both MainWindow and Channel, the one in the MainWindow is for reading server messages not reading channel messages, the one in Channel for reading the channel messages.
4. theres no "4", i think ive explained it all.
its all about a simple irc client, if u can help that would be appreciated.
heres the headers of "Channel" & "MainWindow":
mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QDialog>

#include "channel.h"

class QTabWidget;
class QTcpSocket;
class QLineEdit;
class QLabel;
class QPushButton;
class QTextEdit;

class MainWindow : public QDialog
{
Q_OBJECT
public:
explicit MainWindow(QWidget* parent = 0);

public slots:
void Connect();
void appendToWindow();
void sendMessage();
void displayError(QAbstractSocket::SocketError socketError);

private:
QPushButton *done, *quit, *send;
QLineEdit *write;
QTcpSocket *socket;
QTextEdit *read;
QTabWidget* tabs;
bool connected;
};
#endif

channel.h:

#ifndef CHANNELS_H
#define CHANNELS_H

#include <QWidget>
#include <QTcpSocket>

class QLineEdit;
class QTextEdit;

class Channel : public QWidget
{
Q_OBJECT
public:
Channel(QWidget* parent, const QString& name, QTcpSocket* socket);
void printText(const QString& text);

public slots:
void sendMessage();

private:
QString chan;
QLineEdit* write;
QTextEdit* read;
QTcpSocket* m_socket;
};
#endif

i hope u understand me now.

wysota
20th September 2010, 01:55
because ur asking too many weird questions...
I'm not asking weird questions. I just have to practically extract each piece of answer out of you because you are not eagar to surrender any information willingly.

Let's go back to the beginning...

Please modify your methods so that they contain the following pieces of code:


Channel::printText(const QString& text) {
qDebug() << Q_FUNC_INFO << text;
read->append(text);
}


void MainWindow::appendToWindow() {
// ...

Channel* chan = new Channel(0, QString::fromStdString(channel), 0);
chan->printText(QString::fromLatin1(tmp));
qDebug() << Q_FUNC_INFO << tmp << QString::fromLocal8Bit(tmp);
read->append(tmp);

// ...
}

Please show us the output and the relevant pieces of sourcecode after the changes.

Also, if you are using Qt Creator, please right click on your "read" variable from the "Channel" class, choose "Rename symbol under cursor" (or something like that) and enter "channelText". Do the same for MainWindow::read and rename it to "serverText". Then we won't be confusing the two variables anymore...

Fallen_
20th September 2010, 02:07
void MainWindow::appendToWindow()8‘|ÿÿÿà ¿8?|????
8‘|ÿÿÿÿ
:wineasy1.se.quakenet.org 376 Fallen_ :End of /MOTD command.

void MainWindow::appendToWindow()8‘|ÿÿÿà ¿8?|????
8‘|ÿÿÿÿ
void MainWindow::appendToWindow()[03:07:13] Notice from: Message: on 2 ca 1(4) ft 20(20) tr
[03:07:13] Notice from: Message: on 2 ca 1(4) ft 20(20) tr

[03:07:13] Notice from: Message: on 2 ca 1(4) ft 20(20) tr

:wineasy1.se.quakenet.org 221 Fallen_ +i

void MainWindow::appendToWindow()[03:07:13] Notice from: Message: on 2 ca 1(4) ft 20(20) tr
[03:07:13] Notice from: Message: on 2 ca 1(4) ft 20(20) tr

[03:07:13] Notice from: Message: on 2 ca 1(4) ft 20(20) tr

:Fallen_!~Fallen_@41.199.113.40 MODE Fallen_ +i

void MainWindow::appendToWindow()[03:07:13] Notice from: Message: on 2 ca 1(4) ft 20(20) tr
[03:07:13] Notice from: Message: on 2 ca 1(4) ft 20(20) tr

[03:07:13] Notice from: Message: on 2 ca 1(4) ft 20(20) tr
this is the output

wysota
20th September 2010, 02:22
So there is no output from Channel::printText?

By the way, is this:

8‘|ÿÿÿÿ8?|????
8‘|ÿÿÿÿ

what you expected to print in the text edit (apart from the readable text, of course)?

By the way, your "method" of recognizing the command is extremly error prone. Try passing it a "/JOIN #NOTICE" command and see for yourself. Your client will react on "NOTICE" and not on "JOIN". Also this method is prone to buffer overflows. I don't know why you insist on using this C-style API, you are just asking yourself for trouble there (i.e. try sending a really long (like, over 1000 characters long) notice).

Fallen_
20th September 2010, 02:32
this text wont appear in the channel tab since u join after it has finished sending MOTD. wheres tbscope when u need him the most =_=

wysota
20th September 2010, 02:41
this text wont appear in the channel tab since u join after it has finished sending MOTD.
If by showing things irrelevant to the problem you wanted to discourage me from helping you then you have achieved your goal. 50 posts without progress is probably a record of this forum...

tbscope is probably sleeping. Only I'm crazy enough to be sitting here at this hour.