Knowing where is the segmentation fault happening comparing two files - c++

I have the following structure:
int main(int argc, char **argv) {
try {
FX3USBConnection fx3USB3Connection = FX3USB3Connection();
fx3USB3Connection.send_text_file();
}
catch (ErrorOpeningLib& e) {
printf("Error opening library\n");
return -1;
}
catch (NoDeviceFound& e) {
printf("No device found\n");
return 0;
}
return 0;
}
Within send_text_files, the last thing I do is compare two txt files as follows:
printf("Loopback recieved, checking if I received the same that I sended\n");
files_match(out_text_filename, in_text_filename);
printf("Exited without problem");
return; // (actually implicit)
I already used 2 version of files_match function but the last one is an exact copy of this Compare two files
bool FX3USB3Connection::files_match(const std::string &p1, const std::string &p2) {
bool files_match;
std::ifstream f1(p1, std::ifstream::binary|std::ifstream::ate);
std::ifstream f2(p2, std::ifstream::binary|std::ifstream::ate);
if (f1.fail() || f2.fail()) {
return false; //file problem
}
if (f1.tellg() != f2.tellg()) {
return false; //size mismatch
}
//seek back to beginning and use std::equal to compare contents
f1.seekg(0, std::ifstream::beg);
f2.seekg(0, std::ifstream::beg);
files_match = std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
std::istreambuf_iterator<char>(),
std::istreambuf_iterator<char>(f2.rdbuf()));
f1.close();
f2.close();
if (files_match) { printf("Files match\n"); }
else { printf("Files not equal\n"); }
return files_match;
}
Sometimes I get an error and sometimes I don't. When I get the error I get:
Loopback recieved, checking if I received the same that I sended
Files match
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
So, the print after the call to files_match is not being print so I guess the problem was within the function. However, I do a print just before the return statement and it is printing correctly.
PS: I commented the function files_match and I have no problems.
PS1: The files can have whatever like this character: ¥

Yes, as #john suggested, I had to add the fflush() function. There I realize the error was actually outside all this loop but actually is when getting out of the try{} section. It seams to me that is not managing to destroy the fx3USBConnection.
Thank you! I was so mislead now knowing fprint was actually buffered.

Related

Reason for losing messeges over NNG sockets in raw mode

Some context to my problem:
I need to establish an inter-process communication using C++ and sockets and I picked NNG library for that along with nngpp c++ wrapper. I need to use push/pull protocol so no contexts handling is available to me. I wrote some code based on raw example from nngpp demo. The difference here is that, by using push/pull protocol I split this into two separate programs. One for sending and one for receiving.
Problem descripion:
I need to receive let's say a thousand or more messages per second. For now, all messages are captured only when I send about 50/s. That is way too slow and I do believe it can be done faster. The faster I send, the more I lose. At the moment, when sending 1000msg/s I lose about 150 msgs.
Some words about the code
The code may be in C++17 standard. It is written in object-oriented manner so in the end I want to have a class with "receive" method that would simply give me the received messages. For now, I just print the results on screen. Below, I supply some parts of the project with descriptions:
NOTE msgItem is a struct like that:
struct msgItem {
nng::aio aio;
nng::msg msg;
nng::socket_view itemSock;
explicit msgItem(nng::socket_view sock) : itemSock(sock) {}
};
And it is taken from example mentioned above.
Callback function that is executed when message is received by one of the aio's (callback is passed in constructor of aio object). It aims at checking whether everything was ok with transmission, retrieving my Payload (just string for now) and passing it to queue while a flag is set. Then I want to print those messages from the queue using separate thread.
void ReceiverBase<Payload>::aioCallback(void *arg) try {
msgItem *msgItem = (struct msgItem *)arg;
Payload retMsg{};
auto result = msgItem->aio.result();
if (result != nng::error::success) {
throw nng::exception(result);
}
//Here we extract the message
auto msg = msgItem->aio.release_msg();
auto const *data = static_cast<typename Payload::value_type *>(msg.body().data());
auto const count = msg.body().size()/sizeof(typename Payload::value_type);
std::copy(data, data + count, std::back_inserter(retMsg));
{
std::lock_guard<std::mutex> lk(m_msgMx);
newMessageFlag = true;
m_messageQueue.push(std::move(retMsg));
}
msgItem->itemSock.recv(msgItem->aio);
} catch (const nng::exception &e) {
fprintf(stderr, "server_cb: %s: %s\n", e.who(), e.what());
} catch (...) {
fprintf(stderr, "server_cb: unknown exception\n");
}
Separate thread for listening to the flag change and printing. While loop at the end is for continuous work of the program. I use msgCounter to count successful message receival.
void ReceiverBase<Payload>::start() {
auto listenerLambda = [](){
std::string temp;
while (true) {
std::lock_guard<std::mutex> lg(m_msgMx);
if(newMessageFlag) {
temp = std::move(m_messageQueue.front());
m_messageQueue.pop();
++msgCounter;
std::cout << msgCounter << "\n";
newMessageFlag = false;
}}};
std::thread listenerThread (listenerLambda);
while (true) {
std::this_thread::sleep_for(std::chrono::microseconds(1));
}
}
This is my sender application. I tweak the frequency of msg sending by changing the value in std::chrono::miliseconds(val).
int main (int argc, char *argv[])
{
std::string connection_address{"ipc:///tmp/async_demo1"};
std::string longMsg{" here normally I have some long test text"};
std::cout << "Trying connecting sender:";
StringSender sender(connection_address);
sender.setupConnection();
for (int i=0; i<1000; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(3));
sender.send(longMsg);
}
}
And this is receiver:
int main (int argc, char *argv[])
{
std::string connection_address{"ipc:///tmp/async_demo1"};
std::cout << "Trying connecting receiver:";
StringReceiver receiver(connection_address);
receiver.setupConnection();
std::cout<< "Connection set up. \n";
receiver.start();
return 0;
}
Nothing speciall in those two applications as You see. the setup method from StringReciver is something like that:
bool ReceiverBase<Payload>::setupConnection() {
m_connected = false;
try {
for (size_t i = 0; i < m_parallel; ++i) {
m_msgItems.at(i) = std::make_unique<msgItem>(m_sock);
m_msgItems.at(i)->aio =
nng::aio(ReceiverBase::aioCallback, m_msgItems.at(i).get());
}
m_sock.listen(m_adress.c_str());
m_connected = true;
for (size_t i = 0; i < m_parallel; ++i) {
m_msgItems.at(i)->itemSock.recv(m_msgItems.at(i)->aio);
}
} catch (const nng::exception &e) {
printf("%s: %s\n", e.who(), e.what());
}
return m_connected;
}
Do You have any suggestions why the performance is so low? Do I use lock_guards properly here? What I want them to do is basically lock the flag and queue so only one side has access to it.
NOTE: Adding more listeners thread does not affect the performance either way.
NOTE2: newMessageFlag is atomic

String gets corrupted - stack overflow?

I'm despairing! I want to have my ESP8266 receive a string from a TCP client, execute the corresponding function and give a TCP response. But unfortunately the response string gets corrupted in some strange way:
Assuming that I enter an 'unknown command', the first 11 bytes are printed correctly via the serial interface (the rest is dump) and the first 11 bytes received by the client are dump, but the rest is correct (see comments in script below). But when I enter the 'dim' command the result is correct (but the return string is also shorter than "error: unknown command").
For the moment I have absolutely no idea how to fix this, even though I've tried a lot.
#include <WiFiClient.h>
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <string.h>
struct parsed_query{
String command;
String arguments;
};
struct parsed_query parser(void){
// this function receives and parses a query
struct parsed_query result;
result.command="entered command";
result.arguments="entered arguments"
return result
}
char* str2char(String as_string){
int i_0=0;
while(as_string[i_0]!='\0'){i_0++;}
char as_char[i_0+1];
as_char[i_0]='\0';
for(int i=0;i<i_0;i++){
as_char[i]=as_string[i];
}
return as_char;
}
String executor(String command,String arguments){
String response;
if(command=="dim"){
response="dimming";
}
else if(command=="on"){
response="switching ON";
}
else{
response="error: unknown command";
}
return response;
}
void setup(){
// initialize serial interface, wifi & tcp-server
Serial.begin(115200);
WiFi.begin("<SSID>","<PASSWORD>");
while (WiFi.status() != WL_CONNECTED){delay(500);}
TCPserver.begin();
}
void loop() {
if(!client.connected()){
client=TCPserver.available();
}else{
struct parsed_query query=parser();
// This prints "error: unkno??*/???*??"
Serial.println(str2char(executor(query.command,query.arguments)));
// here, the client receives "????**?*??*?wn command"
client.write(str2char(executor(query.command,query.arguments))));
}
}
I have two ideas what could be causing this result (even though I don't know where to fix it in my code):
Case 1:
Maybe, I meshed up call-by-reference and call-by-value at some point (if yes, where??)
Case 2:
My programm is causing a stack overflow (if yes, where??)
Any help highly appreciated as I don't want to spend one more night.
In str2char you're returning a pointer to a local array, but like every local variable, it doesn't exist anymore after the function has returned. So reading from the returned pointer causes undefined behavior.
Compiling with warnings enabled (which is highly recommended) should output something like:
warning: address of local variable 'as_char' returned
(one) correct code would be
#include <WiFiClient.h>
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <string.h>
#define TCP_RESPONSE_L 1024
struct parsed_query{
String command;
String arguments;
};
struct parsed_query parser(void){
// this function receives and parses a query
struct parsed_query result;
result.command="entered command";
result.arguments="entered arguments"
return result
}
int str2char(char *as_char, String as_string, int max_length){
int i_0=0;
while(as_string[i_0]!='\0'){
if(i_0>=max_length){as_string="error: caught an overflow! increase TCP_BUFFER_L";break;}
i_0++;
}
as_char[i_0]='\0';
for(int i=0;i<i_0;i++){
as_char[i]=as_string[i];
}
return 1;
}
String executor(String command,String arguments){
String response;
if(command=="dim"){
response="dimming";
}
else if(command=="on"){
response="switching ON";
}
else{
response="error: unknown command";
}
return response;
}
void setup(){
// initialize serial interface, wifi & tcp-server
Serial.begin(115200);
WiFi.begin("<SSID>","<PASSWORD>");
while (WiFi.status() != WL_CONNECTED){delay(500);}
TCPserver.begin();
}
void loop() {
if(!client.connected()){
client=TCPserver.available();
}else{
struct parsed_query query=parser();
char response[TCP_RESPONSE_L];
str2char(response,executor(query.command,query.arguments),TCP_RESPONSE_L);
//prints fine
Serial.println(str2char(executor(query.command,query.arguments)));
//correctly sending to client
client.write(str2char(executor(query.command,query.arguments))));
}
}

receiving webpages using windows sockets(C ++),but got some unexpected words

I am trying to get a webpage with sockets,using http GET.I do get the page,but there is something little wrong.
Sometimes I got it all right,but sometimes I got it with wrong characters like:
**<td class="c_ba2636">09</t
1ff8
d>**
it should be :
<td class="c_ba2636">09</td>
I donot know why there is a "1ff8" and some "\r\n".
It happens here and there from time to time.And sometimes it occurs like:
06
again it should be :
<td class="c_ba2636">06</td>
this is how I receive and save the page from a socket:
ofstream out("webpage.html");
char text[2050]="";
int recvbytes=0;
string content;
while ( (recvbytes = recv(sock, text, 2048, 0)) > 0)
{
content=string(text,recvbytes);
out << content.c_str();
//System::Console::Write(gcnew String(content.c_str()));
}
closesocket(sock);
out.close();
I tried :out << text; it did not work.
Please does anyone know what's wrong with my codes.
I am using VS2010,and this is a winform program.
It may be normal if your input text is UTF8 encoded and contains characters out of ASCII space
Now I got it done.it turns out that those "1ff8" "2000" or whatever are from some http protocols,to indicates something(length?).I just need to delete those lines and rearrange the lines that are interrupted by them.So I add a function:
private: void rearrangment()
{
ifstream ifile("webpage.html");
ofstream ofile("web.html");
char line1[2048]="";
char line2[2048]="";
char line3[2048]="";
ifile.getline(line1,2047);
//ifile.getline(line2,2047);
while(!ifile.eof())
{
ifile.getline(line2,2047);
if(string(line2,0,3)!=" "
&& line2[0]!='<' && line2[1]!='<' && line2[2]!='<')//they are "1ff8"s
{
ifile.getline(line3,2047);
for(int i=0;i<2046;++i)
{
if(line1[i]==13)
{
line1[i]=0;
break;
}
}
strcat(line1,line3);
}
else
{
ofile<<line1<<endl;
strcpy(line1,line2);
//ofile<<line1;
}
//ofile<<line1;
}
ifile.close();
ofile.close();
}
and now it works well.
Sorry about this stupid question,I should have searched before I asked.

'SDL_main' : must return a value

I am trying to retreive content of websice in c++ usind SDL but it is giving me this error:
'SDL_main' : must return a value
my code is:
#include <iostream>
#include "SDL.h"
#include "SDL_net.h"
#include <cstring>
int main(int argc,char** argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDLNet_Init();
IPaddress ip;
SDLNet_ResolveHost(&ip,"www.linux.org",80);
const char* http="GET / HTTP/1.1\nHost: www.linux.org\n\n";
TCPsocket client=SDLNet_TCP_Open(&ip);
SDLNet_TCP_Send(client,http,strlen(http)+1);
char text[10000];
while(SDLNet_TCP_Recv(client,text,10000))
std::cout << text;
SDLNet_TCP_Close(client);
SDLNet_Quit();
SDL_Quit();
}
When I put return 0; at the end, it built project but it finished immediately after that
(I am using vs2012)
UPDATE
cout<<"Some message";
doesn't print anything, is it possible that I have configured my imports wrong? are those additional dependencies right?
SDL.lib;SDL_net.lib;SDLmain.lib
I don't know what else could be wrong ...
It's because SDL defines a macro like this:
#define main SDL_main
So the function you've written is actually called SDL_main and like any other function that is not the actual main function, if it doesn't return void, you have to give it a return statement.
because your code doesn't loop forever it just returns 0 after first pass, you need to make a loop like:
while(1){
sdl_events event;
switch(event){
//handle events, drawings and so on
...
...
...
case SDL_QUIT:
exit (0);
break;
}
}
http://sdl.beuc.net/sdl.wiki/OpenGL_Full_Example
UPDATE
you may also have some problem connecting to host so you could check if connection succeed like this:
#define MAXLEN 1024
int result;
char msg[MAXLEN];
result = SDLNet_TCP_Recv(sock,msg,MAXLEN-1);
if(result <= 0) {
// TCP Connection is broken. (because of error or closure)
SDLNet_TCP_Close(sock);
exit(1);
}
else {
msg[result] = 0;
printf("Received: \"%s\"\n",msg);
}
UPDATE 2
change this:
while(SDLNet_TCP_Recv(client,text,10000))
std::cout << text;
to this:
while(SDLNet_TCP_Recv(client,text,9999))
std::cout << text;
UPDATE 3
try this, put your receive part in this if statement
if(SDLNet_SocketReady(client) == 1)
{
while(SDLNet_TCP_Recv(client,text,9999))
std::cout << text;
}
if this still doesn't work I suggest to use QT sockets or Boost asio, both async and more intuitive

Inconsistent behaviour with fopen in C/C++

I'm working with a library which opens the same file many times. It checks the header of the file to make sure that it is the correct format. The first 1212 times it opens the file, it behaves correctly. The 1213th time, the bytes read out from the file are different. Can anyone suggest why this might be happening?
Unfortunately I can't make a small reproducible example - and it takes 20 minutes to run through to this point. So I'm wondering if there are any subtleties of fopen which I might have missed, or something else which might have a bearing on this execution.
The code is below. Many instances of the class are created, and each on has initialise() called with the same filename. The first 1212 times, the output is:
Expecting: '?'
?lon-1800????%#LYB1800????%#LYB100????%#LYB
lat-900??p-2?%#HYB900??p-2?%#HYB10??p-2?%#HYB
? soilcode0 ?? ?-2?&#AYB12 ?? ?-2?&#AYB1 ?? ?-2?&#AYBmtemp-600??x.2?&#6YB600??x.2?&#6YB10??x.2?&#6YB
?mprec0???H2?&#.YB99999???H2?&#.YB1999???H2?&#.YB?msun0???A2?&#%YB1000???A2?&#%YB100???A2?&#%YB
?
Got: '?'
?lon-1800????%#LYB1800????%#LYB100????%#LYB
lat-900??p-2?%#HYB900??p-2?%#HYB10??p-2?%#HYB
? soilcode0 ?? ?-2?&#AYB12 ?? ?-2?&#AYB1 ?? ?-2?&#AYBmtemp-600??x.2?&#6YB600??x.2?&#6YB10??x.2?&#6YB
?mprec0???H2?&#.YB99999???H2?&#.YB1999???H2?&#.YB?msun0???A2?&#%YB1000???A2?&#%YB100???A2?&#%YB
?
The last time I get:
Expecting: '?'
?lon-1800????%#LYB1800????%#LYB100????%#LYB
lat-900??p-2?%#HYB900??p-2?%#HYB10??p-2?%#HYB
? soilcode0 ?? ?-2?&#AYB12 ?? ?-2?&#AYB1 ?? ?-2?&#AYBmtemp-600??x.2?&#6YB600??x.2?&#6YB10??x.2?&#6YB
?mprec0???H2?&#.YB99999???H2?&#.YB1999???H2?&#.YB?msun0???A2?&#%YB1000???A2?&#%YB100???A2?&#%YB
?
Got: ' lon lat year
The function is as follows:
class Archive {
private:
FILE* pfile;
<snip>
bool initialise(char* filename) {
int i;
unsigned char* pheader;
if (pfile) fclose(pfile);
pfile=fopen(filename,"rb");
if (!pfile || pfile == NULL ) {
printf("Could not open %s for input\n",filename);
return false;
}
pheader=new unsigned char[CRU_1901_2002_HEADERSIZE-4];
if (!pheader) {
printf("Out of memory\n");
fclose(pfile);
pfile=NULL;
return false;
}
::rewind(pfile);
fread(pheader,CRU_1901_2002_HEADERSIZE-4,1,pfile);
printf( "Expecting: '%s'\n", CRU_1901_2002_HEADER);
for( int j = 0; j < CRU_1901_2002_HEADERSIZE-4;j++ )
printf( "%c", CRU_1901_2002_HEADER[j]);
printf( "\nGot: '%s'\n", pheader);
for( int j = 0; j < CRU_1901_2002_HEADERSIZE-4;j++ )
printf( "%c", pheader[j]);
printf( "\n");
for (i=0;i<CRU_1901_2002_HEADERSIZE-4;i++) {
if (pheader[i]!=CRU_1901_2002_HEADER[i]) {
fclose(pfile);
pfile=NULL;
delete pheader;
return false;
}
}
delete pheader;
::rewind(pfile);
fseek(pfile,CRU_1901_2002_HEADERSIZE+CRU_1901_2002_DATA_LENGTH*CRU_1901_2002_NRECORD,SEEK_CUR);
recno=0;
iseof=false;
return true;
}
public:
Archive() {
pfile=NULL;
}
Archive() {
if (pfile) fclose(pfile);
}
Are you sure that there is data in the 1213th position? or, are these data are correct?
I suggest you mount a file with more than 1213th records and do a test to confirm if there is a read error or not in this position.
It turns out this is down to too many files being open. Changing the program elsewhere to open less files fixes it.
Checking fread returns 1, except for the last one, where it returns 0.
However, I don't understand why fopen gives back a non-null file pointer when it can't open the file. In test code, it returns NULL, which is then caught as expected.