Write and Read method stop my execution - pipes c++ - c++

I'm just trying to make a "Tree" where I've a ctrsis and (for now) n "Children" connected to the ctrsis by pipes; But something happen when I try to pass data through pipes from childen to parent and parent to children using stdin and stdout, specificly when I use write() cpp function.
//ctrsis.cpp
int
main(void) {
vector<WriteIn> TubesReference;
WriteIn mainTube;
TubesReference.push_back(mainTube);
const char* file = "ctrsis.cfg";
int levelOneProcesses = 0;
string line;
ifstream configFile(file);
if(configFile.is_open()){
while ( getline (configFile,line) ){
WriteIn structure = createTube(line);
TubesReference.push_back(structure);
levelOneProcesses++;
}
}else{
cout << "Unable to open file" << endl;
}
configFile.close();
if ((TubesReference[0].in = open("ctrsis.cfg", O_RDONLY)) == -1) {
std::cerr << "Error open file" << std::endl;
return 1;
}
TubesReference[0].out = TubesReference[1].pipeOut[1];
for (int i = 1; i < levelOneProcesses; ++i){
TubesReference[i].in = TubesReference[i].pipeIn[0];
if(i != TubesReference.size()-1){
TubesReference[i].out = TubesReference[i+1].pipeOut[1];
}else{
TubesReference[TubesReference.size()-1].out = 1;
}
}
pthread_t levelOneThreads[levelOneProcesses];
for(int i = 0; i < levelOneProcesses; ++i){
vector<string> vec;
istringstream iss(TubesReference[i+1].line);
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(vec));
string file = "FICHEROCFG=" + vec[4];
string folder = "DIRDETRABAJO=" + vec[3];
char* formatFile = new char[file.length()+1];
memcpy(formatFile, file.c_str(), file.length()+1);
char* formatFolder= new char[folder.length()+1];
memcpy(formatFolder, folder.c_str(), folder.length()+1);
putenv(formatFile);
putenv(formatFolder);
cout << "CTRSIS: CREATE THREAD " << i << endl;
int ret = pthread_create(&levelOneThreads[i],NULL, readWriteThread, &TubesReference[i]);
if(ret != 0) {
cerr << "Error: pthread_create() failed\n" << endl;
exit(EXIT_FAILURE);
}else{
cout << "CTRSIS: JOIN THREAD " << i << endl;
pthread_join(levelOneThreads[i], NULL);
}
}
//system( "./ctreval" );
return 0;
}
void* readWriteThread(void *arg) {
sleep(3);
WriteIn *dataInOut = (struct WriteIn *) arg;
cout << "CTRSIS: METHOD" << endl;
char c;
while (read(dataInOut->in, &c, 1) > 0) {
write(dataInOut->out, &c, 1);
}
close(dataInOut->in);
close(dataInOut->out);
return NULL;
}
This is the evaluator
#include <iostream>
#include <cctype>
int
main(void) {
int c;
while ((c = std::cin.get()) != EOF) {
c = ::toupper(c);
std::cout << (char) c;
}
return 0;
}

Related

Parallel child processes with fork() and pipe(): Bad file descriptor and unpredictable behaviour

I try to set up parallel calculations in processes instead of threads. I started with a very simple example: send an integer from parent process to child process. It works and this is the code of the function processParallel1():
//parent sends integer to child
bool processParallel1()
{
//define pipe
int parent2Child[2];
//create pipe
pipe(parent2Child);
//fork
pid_t child = fork();
if(child == 0) //child process
{
//close not needed end of pipe
close(parent2Child[1]);
for(;;)
{
struct pollfd pfd;
pfd.fd = parent2Child[0];
pfd.events = POLLIN;
//wait until data is available at the pipe
if(poll(&pfd, 1, -1) < 0)
{
cout << strerror(errno) << endl;
return false;
}
if((pfd.revents&POLLIN) == POLLIN)
{
int data;
if(!readData1(parent2Child[0], data))
return false;
cout << "c: received data: " << strerror(errno) << endl;
cout << "data received: " << data << endl;
if(data == -1)
break;
}
}
exit(0);
}
else //parent process
{
//close not needed end of pipe
close(parent2Child[0]);
//send data to child
if(!writeData1(parent2Child[1], 136758))
return false;
cout << "p: wrote data: " << strerror(errno) << endl;
//send stop data
if(!writeData1(parent2Child[1], -1))
return false;
cout << "p: wrote data: " << strerror(errno) << endl;
//wait for child to end
wait(nullptr);
//close all pipes
close(parent2Child[0]);
close(parent2Child[1]);
}
return true;
}
In processParallel1() I use this methods for writing and reading to the pipe:
bool writeData1(int fd, const int data)
{
int bytesWritten = write(fd, &data, sizeof(int));
if(bytesWritten < 0)
{
cout << strerror(errno) << endl;
return false;
}
return true;
}
bool readData1(int fd, int & data)
{
char intBuf[sizeof(int)];
int bytesRead = read(fd, intBuf, sizeof(int));
if(bytesRead > 0)
{
data = *(int *)intBuf;
}
else if(bytesRead < 0)
{
cout << strerror(errno) << endl;
return false;
}
return true;
}
Everything works as expected. Now I add more data and it becomes strange. I only exchanged the methods for writing and reading (and created a new version of the method now named processParallel3()):
bool writeData3(int fd, const int number, const std::string text)
{
int bytesWritten = write(fd, &number, sizeof(int));
if(bytesWritten < 0)
{
cout << strerror(errno) << endl;
return false;
}
int size = text.size() + 1;
bytesWritten = write(fd, &size, sizeof(int));
if(bytesWritten < 0)
{
cout << strerror(errno) << endl;
return false;
}
bytesWritten = write(fd, text.c_str(), size);
if(bytesWritten < 0)
{
cout << strerror(errno) << endl;
return false;
}
return true;
}
bool readData3(int fd, int & number, std::string & text)
{
char numberBuf[sizeof(int)];
int bytesRead = read(fd, numberBuf, sizeof(int));
if(bytesRead > 0)
{
number = *(int *)numberBuf;
}
else if(bytesRead < 0)
{
cout << strerror(errno) << endl;
return false;
}
char sizeBuf[sizeof(int)];
int size = -1;
bytesRead = read(fd, sizeBuf, sizeof(int));
if(bytesRead > 0)
{
size = *(int *)sizeBuf;
}
else if(bytesRead < 0)
{
cout << strerror(errno) << endl;
return false;
}
char textBuf[size];
bytesRead = read(fd, textBuf, size);
if(bytesRead > 0)
{
text = std::string(textBuf);
}
else if(bytesRead < 0)
{
cout << strerror(errno) << endl;
return false;
}
return true;
}
When I run processParallel3() in a main I get three times a "Success" after writing and reading, but the methods hangs after printing the received data in the child.
When I add the method processParallel1() to be run directly before processParallel3() in 1 everything is ok, but now I get three times "Bad file descriptor" and it hangs again.
Any idea what could happen or what further tests I could run?

How can I improve file read performance?

I created a c++ program that reads and analyzes pcap files via fread function.
It is a program that reads the global header of pcap file, reads the pcap header, and extracts a specific field value by specifying each protocol header structure. Compared to tcpdump tool, tcpdump read the pcap file about three times faster. My program is really simple, but I don't know why it is slow. What do I need to do to improve my program's performance?
The following is my code. Note that the type of result(Variable) is ostringstream. and The Program is work by calling analyze() repeatly to read all the pcap files.
PcapAnalyzer::PcapAnalyzer(const std::string& filename)
{
PcapAnalyzerfile = fopen("test.pcap", "r");
if (PcapAnalyzerfile == nullptr)
throw std::runtime_error("Failed to read Pcap");
struct PcapAnalyzer_file_header pfh;
if (fread(&pfh, sizeof(pfh), 1, PcapAnalyzerfile) < 1)
throw std::runtime_error("Failed to read Pcap");
if(pfh.linktype != 1)
throw std::runtime_error("No Support");
}
std::string PcapAnalyzer::analyze()
{
int process_len = 0;
int packet_len = 0;
result.str("");
result.clear();
packet_len = PcapAnalyzer_header();
if (packet_len == -1)
return {};
process_len = ethernet();
if (process_len == -1)
throw std::runtime_error("failed to analyze");
packet_len -= process_len;
if (!payload(packet_len))
throw std::runtime_error("failed to analyze");
return result.str();
}
int PcapAnalyzer::PcapAnalyzer_header()
{
struct PcapAnalyzer_pkthdr pp;
char* cap_time;
long sec;
if (fread(&pp, sizeof(pp), 1, PcapAnalyzerfile) < 1)
return -1;
sec = (long)pp.ts.tv_sec;
cap_time = (char*)ctime((const time_t*)&sec);
cap_time[strlen(cap_time) - 1] = '\0';
result << std::dec;
result << pp.len << " ";
result << cap_time << " ";
return pp.caplen;
}
int PcapAnalyzer::ethernet()
{
struct ether_header eh;
int process_len = 0;
if (fread(&eh, sizeof(eh), 1, PcapAnalyzerfile) < 1)
return -1;
process_len += sizeof(eh);
if(htons(eh.ether_type) != ETHERTYPE_IP)
return process_len;
process_len += ipv4();
if (process_len == -1)
throw std::runtime_error("failed to analyze");
return process_len;
}
int PcapAnalyzer::ipv4()
{
struct ip iph;
int opt = 0;
int process_len = 0;
if (fread(&iph, 20, 1, PcapAnalyzerfile) < 1)
return -1;
result << IP_V(iph.ip_vhl) << " ";
result << IP_HL(iph.ip_vhl) << " ";
result << iph.ip_tos << " ";
result << iph.ip_len << " ";
result << iph.ip_id << " ";
result << iph.ip_off << " ";
result << iph.ip_ttl << " ";
process_len += 20;
opt = IP_HL(iph.ip_vhl) * 4 - sizeof(iph);
if (opt != 0) {
fseek(PcapAnalyzerfile, opt, SEEK_CUR);
process_len += opt;
result << "ip_opt ";
}
if(iph.ip_p != IPPROTO_UDP)
return process_len;
process_len += udp();
if (process_len == -1)
throw std::runtime_error("failed to read transport header");
return process_len;
}
int PcapAnalyzer::udp()
{
struct udphdr udph;
int process_len = 0;
if (fread(&udph, sizeof(udph), 1, PcapAnalyzerfile) < 1)
return -1;
process_len += sizeof(udph);
result << ntohs(udph.uh_sport) << " ";
result << ntohs(udph.uh_dport) << " ";
result << ntohs(udph.uh_ulen) << " ";
result << ntohs(udph.uh_sum) << " ";
return process_len;
}
bool PcapAnalyzer::payload(int remain_len)
{
if (remain_len == 0)
return true;
char buffer[remain_len];
if (fread(buffer, remain_len, 1, PcapAnalyzerfile) < 1)
return false;
return true;
}

Can't send data to HID with libusb on windows

I'm currently trying to make a little piece of code that receive and send data to a HID (Texas Instrument HDK). There is no bug on the embedded system code (i can send data with a java program on mac OS to the device).
The reception is working but i can't send data (always getting error io return code).
Here's the code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include "libusb.h"
const static int PACKET_INT_LEN = 4;
const static int INTERFACE = 0;
const static int ENDPOINT_INT_IN = 0x83; /* endpoint 3 address for IN */
const static int ENDPOINT_INT_OUT = 0x04; /* endpoint 4 address for OUT */
const static int TIMEOUT = 5000;
#pragma comment(lib, "libusb-1.0.lib")
using namespace std;
libusb_device ** DoList();
libusb_device_handle * GetDevice(libusb_device ** deviceList);
int test_interrupt_transfer(libusb_device_handle * devh);
void error_interrupt_transfert(int r);
int main()
{
libusb_context ** context = NULL;
libusb_device_handle * deviceHandle = NULL;
int result_init = 0;
result_init = libusb_init(context);
if (result_init < 0)
cout << "Failed to init libusb." << endl;
else
deviceHandle = GetDevice(DoList());
int err = libusb_kernel_driver_active(deviceHandle, 0);
if (err >= LIBUSB_SUCCESS)
{
if (err == 1)
{
printf("Kernel driver is active, trying to detach");
err = libusb_detach_kernel_driver(deviceHandle, 0);
if (err != LIBUSB_SUCCESS)
{
printf("Error detaching interface from kernel");
}
}
}
if (libusb_kernel_driver_active(deviceHandle, 0) == 1)
{
if (libusb_detach_kernel_driver(deviceHandle, 0) == 0)
cout << "Kernel driver detatched !" << endl;
}
while (1)
{
test_interrupt_transfer(deviceHandle);
cout << 1 << endl;
Sleep(3000);
}
system("pause");
}
libusb_device ** DoList()
{
libusb_device **devs;
ssize_t count;
count = libusb_get_device_list(NULL, &devs);
if (count < 0)
{
cout << "Failed to get device list";
return NULL;
}
libusb_device *dev;
int i = 0;
cout << "Device list" << endl;
while ((dev = devs[i++]) != NULL)
{
struct libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(dev, &desc);
if (r < 0)
{
cout << "Failed to get device descriptor" << endl;
return NULL;
}
printf("\t%04x:%04x (bus %d, device %d)\n",
desc.idVendor, desc.idProduct,
libusb_get_bus_number(dev), libusb_get_device_address(dev));
}
return devs;
}
libusb_device_handle * GetDevice(libusb_device ** devList)
{
int i = 0,
vid = 0x1cbe,
pid = 0;
libusb_device * dev;
libusb_device_handle * handle = NULL;
unsigned char strDesc[256];
if (devList == NULL)
{
return NULL;
}
while ((dev = devList[i++]) != NULL)
{
struct libusb_device_descriptor desc;
struct libusb_config_descriptor ** conDesc = NULL;
int ret = libusb_get_device_descriptor(dev, &desc);
if (ret < 0)
{
cout << "Failed libusb_get_device_descriptor" << endl;
continue;
}
if (desc.idVendor == vid && desc.idProduct == pid)
{
int ret = libusb_open(dev, &handle);
if (ret < 0)
{
cout << "Failed libusb_open" << ret << endl;
break;
}
ret = libusb_claim_interface(handle, 0);
if (ret < 0)
{
cout << "Failed libusb_claim_interface" << endl;
libusb_close(handle);
handle = NULL;
break;
}
libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, strDesc, 256);
printf(" Manufacturer = %s\n", strDesc);
libusb_get_string_descriptor_ascii(handle, desc.iProduct, strDesc, 256);
printf(" Product = %s\n", strDesc);
libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, strDesc, 256);
printf(" Serial number = %s\n", strDesc);
break;
}
}
cout << "Success openning device" << endl;
libusb_free_device_list(devList, 1);
return handle;
}
int test_interrupt_transfer(libusb_device_handle * devh)
{
int r, i;
int transferred = 0;
int * ptransferred = &transferred;
unsigned char answer[PACKET_INT_LEN];
unsigned char question[2];
r = libusb_interrupt_transfer(devh, ENDPOINT_INT_OUT, question,
sizeof(question), ptransferred, TIMEOUT);
if (r < 0) {
error_interrupt_transfert(r);
return r;
}
r = libusb_interrupt_transfer(devh, ENDPOINT_INT_IN, answer, PACKET_INT_LEN,
&transferred, TIMEOUT);
if (r < 0)
{
error_interrupt_transfert(r);
return r;
}
for (i = 0; i < PACKET_INT_LEN; i++)
{
printf("%02x; ", answer[i]);
}
printf("\n");
return 0;
}
void error_interrupt_transfert(int r)
{
switch (r)
{
case LIBUSB_SUCCESS: cout << "Success" << endl;
break;
case LIBUSB_ERROR_TIMEOUT: cout << "Timeout" << endl;
break;
case LIBUSB_ERROR_PIPE: cout << "Error pipe" << endl;
break;
case LIBUSB_ERROR_OVERFLOW: cout << "Overflow" << endl;
break;
case LIBUSB_ERROR_NO_DEVICE: cout << "No device" << endl;
break;
case LIBUSB_ERROR_IO: cout << "Error IO" << endl;
break;
case LIBUSB_ERROR_NOT_FOUND: cout << "Not found" << endl;
break;
case LIBUSB_ERROR_INVALID_PARAM: cout << "Invalid param" << endl;
break;
case LIBUSB_ERROR_ACCESS: cout << "Error access" << endl;
break;
case LIBUSB_ERROR_INTERRUPTED: cout << "Interrupted" << endl;
break;
case LIBUSB_ERROR_BUSY: cout << "Busy" << endl;
break;
case LIBUSB_ERROR_NO_MEM: cout << "No memory" << endl;
break;
case LIBUSB_ERROR_NOT_SUPPORTED: cout << "Not supported" << endl;
break;
case LIBUSB_ERROR_OTHER: cout << "Other" << endl;
break;
default: cout << "Unknow error code" << r << endl;
}
}
Any idea folks?
Calmant Kévin

Memory leak when using sqlite3 with C++

The program writes into SQLite database, the messages are received through a wireless module. But somehow there is a memory leak every time a message is received and written to the database, after about 10 000 writes the program is using 1GB of memory.
The documentation for SQLite3 with C++ says that memory leaks are prevented with sqlite3_finalize() and sqlite3_close() which are present:
#include <iostream>
#include <string>
#include <sstream>
#include "sqlite3.h"
using namespace std;
#define DB "test.db"
sqlite3 *dbfile;
bool connectDB();
void disonnectDB();
int insOrUpdate(string s);
int select(string s);
struct messageStruct_t {
float value;
};
bool isOpenDB = false;
int main() {
int counter = 0;
while (1) {
int header = 1;
int message = rand() % 3;
if (message) {
counter ++;
switch (header) {
case 1: {
messageStruct_t recMessage;
recMessage.value = 55;
int receivedSendersID = 2;
//SQL query to get foreign key
stringstream strm_select;
strm_select << "SELECT id FROM table1 WHERE sendersID="
<< receivedSendersID;
string s_select = strm_select.str();
cout << "SQL query: " << s_select << endl;
int sendersID = select(s_select);
cout << "Sender's ID: " << sendersID << endl;
if (sendersID == 0) {
cout << "Error: Sender doesn't exist\n";
} else {
stringstream strm_insert;
strm_insert << "INSERT into table2(id,value,sender_id) values("
<< counter << ", "
<< recMessage.value << ", " << sendersID << ")";
string s_insert = strm_insert.str();
cout << "SQL query: " << s_insert << endl;
insOrUpdate(s_insert);
cout << "Recorded data: " << recMessage.value << endl;
}
}
default: {
break;
}
}
}
}
}
bool connectDB () {
if (sqlite3_open(DB, &dbfile) == SQLITE_OK) {
isOpenDB = true;
return true;
}
return false;
}
void disonnectDB () {
if ( isOpenDB == true ) {
sqlite3_close(dbfile);
}
}
int insOrUpdate(string s) {
if (!connectDB()) {
return 0;
}
char *str = &s[0];
sqlite3_stmt *statement;
int result;
const char *query = str;
if (sqlite3_prepare(dbfile, query, -1, &statement, 0) == SQLITE_OK) {
result = sqlite3_step(statement);
//the documentation says that this destroys the statement and prevents memory leaks
sqlite3_finalize(statement);
return result;
}
//and this destroys the db object and prevents memory leaks
disonnectDB();
return 0;
}
int select(string s) {
if (!connectDB()) {
return 0;
}
char *str = &s[0];
sqlite3_stmt *statement;
const char *query = str;
string returned;
if (sqlite3_prepare(dbfile, query, -1, &statement, 0) == SQLITE_OK) {
int ctotal = sqlite3_column_count(statement);
int res = 0;
while (1) {
res = sqlite3_step(statement);
if (res == SQLITE_ROW) {
for (int i = 0; i < ctotal; i++) {
string s = (char*)sqlite3_column_text(statement, i);
cout << s << " ";
returned = s;
}
cout << endl;
}
if (res == SQLITE_DONE || res == SQLITE_ERROR) {
cout << "done " << endl;
break;
}
}
} else {
cout << "Can't prepare" << endl;
return 0;
}
sqlite3_finalize(statement);
disonnectDB();
int result;
stringstream convert(returned);
if (!(convert >> result)) {
result = 0;
}
return result;
}
CREATE TABLE table1 (
id INTEGER NOT NULL,
sendersID INTEGER,
PRIMARY KEY (id)
);
CREATE TABLE table2 (
id INTEGER NOT NULL,
value FLOAT,
sender_id INTEGER,
FOREIGN KEY(sender_id) REFERENCES table1 (id)
);
INSERT INTO table1(sendersID) values(2);
In your connectDB(..) call , you don't check if the database is already open before opening it again. Your memory leak is probably from the repeated mappings of this database into your memory space.
There may be other issues with this program but the change below to connectDB(..) should help with the leak on every successful insert.
bool connectDB() {
if (false == isOpenDB && sqlite3_open(DB, &dbfile) == SQLITE_OK) {
isOpenDB = true;
}
return isOpenDB;
}
You should definitely use RAII for your connections and also for your statements. There are several places where you return early without cleaning up statements and/or closing the connection.

Seg Fault - Signal received, SIGABORT

So my code compiles well, but whenever I try running the program, it seg faults. I ran it through gdb and got this set of error:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Program received signal SIGABRT, Aborted.
0x00007ffff722bcc9 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
Here is my code if it helps:
using namespace std;
#include <iostream>
#include <vector>
#include <cmath>
#include<fstream>
#include <cstdlib>
#include <utility>
#include <string>
class Page
{
public:
int TimeStamp;
int ProgramOwner;
int LocalPageNumber;
};
//Pair: first entry is local page, second entry is global page
//Second entry: 1 if in main memory, 0 if not
class Program
{
public:
vector< pair<int,int> > MemoryMap;
};
class Memory
{
public:
vector<Program> Programs;
vector<Page> Pages;
};
void checkArguments(int argc, char *argv[]);
bool checkPageAlgorithm(char *argv[]);
bool checkPageSize(int pagesize);
bool checkPageStyle(char *argv[]);
bool checkPTrace(string ProgramTraceFile);
bool checkPList(string ProgramListFile);
int main(int argc, char *argv[])
{
//checkArguments(argc, argv);
const int MemSize = 512;
int pageSize = atoi(argv[3]);
string programListFile = argv[1];
string ProgramTraceFile = argv[2];
string pageAlgorithm = argv[4];
string pageStyle = argv[5];
int programNumber;
int programSize;
int PagesNeeded;
Memory MainMemory;
int numberFrames;
int pageFaults = 0;
int numPrograms = 0;
int PagesPerProgram;
int LocalPage;
int activeProgram;
int requestedLocation;
int newPageLocation;
bool foundInMemory;
ifstream fileIn;
fileIn.open(programListFile.c_str());
if(fileIn.fail())
{
cerr << "List file not found." << endl;
fileIn.close();
exit(1);
}
else
{
while(!fileIn.eof())
{
cout << "hey0";
fileIn >> programNumber;
fileIn >> programSize;
numPrograms++;
}
}
numberFrames = ceil(MemSize/pageSize);
PagesPerProgram = ceil(numberFrames/numPrograms);
MainMemory.Pages.resize(numberFrames);
cout << "hey1";
while(!fileIn.eof())
{
cout << "hey2";
fileIn >> programNumber;
fileIn >> programSize;
cout << "hey3";
PagesNeeded = ceil(programSize/pageSize);
for(int i = 0; i < PagesNeeded; i++)
{
LocalPage = i;
MainMemory.Pages[i].ProgramOwner = programNumber;
MainMemory.Pages[i].LocalPageNumber = LocalPage;
}
cout << "hey3";
if(PagesNeeded > PagesPerProgram)
PagesNeeded = PagesPerProgram;
for(int i = 0; i < PagesNeeded; i++)
{
MainMemory.Programs[programNumber].MemoryMap[i].first = MainMemory.Pages[i].LocalPageNumber;
MainMemory.Programs[programNumber].MemoryMap[i].second = 1;
if(pageAlgorithm == "clock")
MainMemory.Pages[i].TimeStamp = 1;
else
MainMemory.Pages[i].TimeStamp = 0;
}
}
fileIn.close();
//LRU Algorithm Implementation
if(pageAlgorithm == "lru")
{
cout << "here1";
fileIn.open(ProgramTraceFile.c_str());
if(fileIn.fail())
{
cerr << "That file does not exist." << endl;
fileIn.close();
exit(1);
}
else
{
fileIn >> activeProgram;
fileIn >> requestedLocation;
newPageLocation = ceil(requestedLocation/pageSize);
while(!fileIn.eof())
{
foundInMemory = false;
for(int i = 0; i < static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()); i++)
{
if((MainMemory.Programs[activeProgram].MemoryMap[i].second == 1) &&
(MainMemory.Programs[activeProgram].MemoryMap[i].first == newPageLocation))
foundInMemory = true;
if(foundInMemory)
break;
}
if(!foundInMemory)
{
pageFaults++;
if(static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()) < PagesPerProgram)
{
pair<int, int> temp;
temp.first = newPageLocation;
temp.second = 1;
MainMemory.Programs[activeProgram].MemoryMap.push_back(temp);
}
else
{
for(int i = 0; i < (static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()) - 1); i++)
{
if(MainMemory.Pages[i].TimeStamp >= MainMemory.Pages[i+1].TimeStamp)
{
MainMemory.Programs[activeProgram].MemoryMap[i].first = newPageLocation;
}
if(pageStyle == "1")
{
if(MainMemory.Pages[i].TimeStamp >= MainMemory.Pages[i+1].TimeStamp)
{
MainMemory.Programs[activeProgram].MemoryMap[i].first = MainMemory.Pages[i].LocalPageNumber;
}
}
MainMemory.Pages[i].TimeStamp++;
}
}
}
fileIn >> activeProgram;
fileIn >> requestedLocation;
newPageLocation = ceil(requestedLocation/pageSize);
}
}
}
cout << "------------------------------------" << endl;
cout << "Page Size: " << pageSize << endl;
cout << "Page Replacement Algorithm: " << pageAlgorithm << endl;
cout << "Paging Style: ";
if(pageStyle == "0")
cout << "Demand" << endl;
else
cout << "Prepaging" << endl;
cout << "Number of Page Faults: " << pageFaults << endl;
cout << "------------------------------------" << endl;
return 0;
}
bool checkPList(string programlistfile)
{
ifstream ListFile(programlistfile.c_str());
if(ListFile.fail())
{
cerr << "Cannot find file " << programlistfile << endl;
ListFile.close();
return false;
}
else
{
ListFile.close();
return true;
}
}
bool checkPTrace(string programTraceFile)
{
ifstream TraceFile;
TraceFile.open(programTraceFile.c_str());
if(TraceFile.fail())
{
cerr << "Cannot find file " << programTraceFile << endl;
TraceFile.close();
return false;
}
else
{
TraceFile.close();
return true;
}
}
bool checkPageStyle(string pageStyle)
{
if(pageStyle == "0")
return true;
else if(pageStyle == "1")
return true;
else
{
cerr << "Page Style can be: 0 or 1." << endl;
return false;
}
}
bool checkPageSize(int pagesize)
{
bool isValid = false;
switch(pagesize)
{
case 1:
isValid = true;
break;
case 2:
isValid = true;
break;
case 4:
isValid = true;
break;
case 8:
isValid = true;
break;
case 16:
isValid = true;
break;
default:
cerr << "Page Size can be: 1, 2, 4, 8, or 16." << endl;
isValid = false;
}
return isValid;
}
bool checkPageAlgorithm(string pageAlgorithm)
{
if(pageAlgorithm == "lru")
return true;
else if(pageAlgorithm == "fifo")
return true;
else if(pageAlgorithm == "clock")
return true;
else
{
cerr << "Valid Page Algorithms are: lru, fifo, or clock" << endl;
return false;
}
}
void checkArguments(int argc, char *argv[])
{
if(argc < 6)
{
cerr << "Invalid number of arguments. Should be: programlist programtrace pagesize pagealgorithm pagingstyle" << endl;
exit(1);
}
else if(argc > 6)
{
cerr << "Invalid number of arguments. Should be: programlist programtrace pagesize pagealgorithm pagingstyle" << endl;
exit(1);
}
else if(!checkPageAlgorithm(argv[4]))
exit(1);
else if(!checkPageSize(atoi(argv[3])))
exit(1);
else if(!checkPageStyle(argv[5]))
exit(1);
else if(!checkPTrace(argv[2]))
exit(1);
else if(!checkPList(argv[1]))
exit(1);
return;
}
The output 'heys' are just to see if they get triggered within gdb, which they don't.
You forgot to actually ask any question.
Presumably, your question is "why does my program die with SIGABRT?"
The answer was provided by the program itself: you've tried to construct std::string from a NULL character pointer, which throws std::logic_error exception (because it's not a valid thing to do).
You may have a follow-up quesiton: "where in my program does this happen?".
You could find the answer by using GDB where command. As a first guess, you didn't invoke your program with sufficient number of arguments. For example, if you did this:
gdb ./a.out
(gdb) run
then argv[1] is NULL, and this statement:
string programListFile = argv[1];
would throw the exception you are getting.
The common solution to this problem is to insist that you do have correct number of arguments, e.g. put this:
if (argc < 6) {
std::cerr << "Not enough arguments" << std::endl;
return 1;
}
at the start of main. Or just comment the call to checkArguments() back in.