Fixing Segmentation Fault - c++

I have to run this code for my class, most of what we use is java, I don't really know c++, but the code I have to run is c++, so I'm finding it difficult to debug or know what's going wrong. To compile it, I'm using a unix virtual machine. I've compiled it and have the a.out file in my directory. When I run the a.out file it says "segmentation fault". I've read that means it's trying to access something it can't, but I don't know what that would be. Is it a problem with the code they gave us, or could it be something like a setting on my machine?
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char *argv[])
{
int N;
sscanf(argv[1], "%d", &N);
vector<double> data(N);
for(unsigned int i=0; i<N; i++) {
data[i] = rand()/(RAND_MAX+1.0);
}
sort(data.begin(), data.end());
copy(data.begin(), data.end(), ostream_iterator<double>(cout,"\n"));
}

This seems to be a matter of how you invoke the compiled binary. Say the executable is a.out, you should execute the program as
./a.out 42
as in this snippet
sscanf(argv[1], "%d", &N);
the size of the std::vector is parsed from the command line arguments. If you don't pass any arguments, argv has only one element (the executable name), and argv[1] is an out of bounds access, yielding undefined behavior. Note that you can use the argc variable to do some rudimentary error handling up front:
int N = 42; // some sensible default value
if (argc == 2)
sscanf(argv[1], "%d", &N);
This still won't protect you from trouble if the given argument is not parsable as an integer, but if you want to get into this, consider using a library for parsing command line options.

Related

Using a program(.exe), inside a program, but passing command line arguments on linux C++

I've been trying to call a program inside another c++ program using the command "execvp()" from the <unistd.h> library but it gets core dump, and i dont know what i am doing wrong;
below its the code i use to call the program i want to use
#include <iostream>
#include <unistd.h>
int main(int argc, char **argv)
{
char *argument_list[]={argv[1],argv[2],NULL};
char *filename = "./bin/program.exe";
execvp(filename, argument_list);
return 0;
}
below this, its the code of the program i want to call
#include <iostream>
int main(int argc, char **argv)
{
int a = atoi(argv[1]);
int b = atoi(argv[2]);
std::cout << a+b<<std::endl;
return 0;
}
when i compile the the first code, i get a "main.exe" binary, then i type "main.exe 5 6" to sum both integers, and i get the "core dump" error.
Curious thing is, if i run gdb on it, i get the sum i want
the first command line, its running directly the "child" program, showing that it works. The second command line, its using the "main" program that calls the child one
(Obviously, this programs aren't the ones i need to apply this, they're just for illustration of the problem, they're really big codes, and it wouldn't be helpful to post them here);
How can i fix this?
So, it works if i set the first argument as the filename, as said by #WhozCraig, so now it works, and looks like this:
#include
#include <unistd.h>
int main(int argc, char **argv)
{
char *argument_list[]={"program.exe",argv[1],argv[2],NULL};
char *filename = "./bin/program.exe";
execvp(filename, argument_list);
return 0;
}
However, i get this warning:
1
How can i get around it? Is there a problem leaving it like this?

gcc FORTIFY_SOURCE drastically increases binary size

We have a very large C++ codebase that we would like to compile using gcc with the "FORTIFY_SOURCE=2" option to improve security and reduce the risk of buffer overflows. The problem is when we compile the system using FORTIFY_SOURCE, the binary sizes drastically increase. (From a total of 4GB to over 25GB) This causes issues when we need to deploy the code because it takes 5x as long to zip it up and deploy it.
In an attempt to figure out what was going on, I made a simple test program that does a bunch of string copies with strcpy (one of the functions FORTIFY_SOURCE is supposed to enhance and compiled it both with and without "FORTIFY_SOURCE".
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char buf1[100];
char buf2[100];
char buf3[100];
char buf4[100];
char buf5[100];
char buf6[100];
char buf7[100];
char buf8[100];
char buf9[100];
char buf10[100];
strcpy(buf1, "this is a string");
strcpy(buf2, "this is a string");
strcpy(buf3, "this is a string");
strcpy(buf4, "this is a string");
strcpy(buf5, "this is a string");
strcpy(buf6, "this is a string");
strcpy(buf7, "this is a string");
strcpy(buf8, "this is a string");
strcpy(buf9, "this is a string");
strcpy(buf10, "this is a string");
}
Compilation:
g++ -o main -O3 fortify_test.cpp
and
g++ -o main -D_FORTIFY_SOURCE=2 -O3 fortify_test.cpp
I discovered that using "FORTIFY_SOURCE" on a simple example had no noticeable impact on binary size (the resulting binary was 8.4K with and without fortifying the source.)
When there's no noticeable impact with a simple example, I wouldn't expect to see such a drastic size increase in more complex examples. What could FORTIFY_SOURCE possibly be doing to increase our binary sizes so drastically?
Your example is actually a not very good one because there's no fortifiable code on it. Code fortification is not magical, and the compiler can only do it under some specific conditions.
Lets take a sample of code with 2 functions, one can be fortified by the compiler (because from the code itself it can determine the maximum size of the buffer), the other cannot (because same information is missing):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
int f_protected(char *in)
{
char buffer[256];
memcpy(buffer, in, strlen(in));
printf("Hello %s !\n", buffer);
return 0;
}
int f_not_protected(char *in, int sz)
{
char buffer[sz];
memcpy(buffer, in, strlen(in));
printf("Hello %s !\n", buffer);
return 0;
}
int main (int argc, char **argv, char **envp)
{
if(argc < 2){
printf("Usage: %s <some string>\n", argv[0]);
exit(EXIT_SUCCESS);
}
f_protected(argv[1]);
f_not_protected(argv[1], strlen(argv[1]));
return 0;
}
There's an amazing online tool that allows you compared compiled code at https://godbolt.org/
You can actually compare both compiled versions of this sample here.
As you will be able to see in the ASM output, the fortified version of this function does perform more checks than the unfortified one, requiring extra ASM code, actually increasing file size.
However, it's hard to think of a case where it would increment code size so much. Is it possible that maybe you're not stripping debug info?

Ifstream is failing to load a file and it won't open

Some of this code may seem foreign to you since I make 3ds homebrew programs for fun but it's essentially the same but with extra lines of code you can put in. I'm trying to read a file called about.txt in a separate folder. I made it work when I put it in the same folder but i lost that file and then my partner said he wanted it in Scratch3ds-master\assets\english\text and not in Scratch3ds-master\source I keep getting the error I coded in. I'm new to stack-overflow so this might be too much code but well here's the code:
#include <fstream>
#include <string>
#include <iostream>
int main()
{
// Initialize the services
gfxInitDefault();
consoleInit(GFX_TOP, NULL);
int version_major;
int version_minor;
int version_patch;
version_major = 0;
version_minor = 0;
version_patch = 2;
printf("This is the placeholder for Scratch3ds\n\n");
std::ifstream about_file;
about_file.open("../assets/english/text/about.txt");
if (about_file.fail())
{
std::cerr << "file has failed to load\n";
exit(1);
}
Chance are that you're using devkitpro packages. And chances are that the devkitpro team provide an equivalent of the NDS 'ARGV protocol' for 3DS programming. In which case, if you use
int main(int argc, char* argv[]);
you should have the full path to your executable in argv[0] if argc is non-zero.
https://devkitpro.org/wiki/Homebrew_Menu might help.
Your program has no a priori knowledge of what sort of arguments main() should receive, and in your question, you're using a main function that receives no argument at all.
Established standard for C/C++ programming is that main() will receive an array of constant C strings (typically named argv for arguments values) and the number of valid entries in that array (typically named argc for count). If you replace your original code with
#include <fstream>
#include <string>
#include <iostream>
int main(int argc, char* argv[])
{
// Initialize the services
// ... more code follows
then you're able to tell whether you received argument by testing argc > 0 and you'll be able to get these arguments values with argv[i].
With homebrew development, it is unlikely that you can pass arguments such as --force or --directory=/boot as on typical command-line tools, but there is one thing that is still useful: the very first entry in argv is supposed to be a full path for the running program. so you're welcome to try
std::cerr << ((argc > 0) ? argv[0] : "<no arguments>");
and see what you get.

What's wrong with std::strings

Hi I am new to C++ and Code::Block
I am trying to make a simple code to test it, using strings.
when I compile the code there is no problem, but when I try to debug it, Code::Block gives me the following warning:
Cannot open file:
File:../../../../../src/gcc-4.9.2/libgcc/unwind-sjlj.c
Info: "Multiple information windows with the same message have been
supressed."
Image of the error FYI:
Part of the code that gives me an error.
inside main function
#include <iostream>
#include <string>
int main ()
{
std::mystring("What's wrong with strings");
return 0;
}
I realise that this error only occurs when I try to debug a string or a file containing a string.
Any help would be appreciated.
some other information that might help:
Code::Block 16.01
Compiler MinGW gcc4.9.2
Windows 7 Professional 32 bits SP1
First of all, to use strings you must include the file header string. And the name of the type string is..std::string, not std::mystring.
#include <string>
int main(int argc, char** argv)
{
std::string mystring("Nothing's wrong with strings");
return 0;
}
#include <iostream>
using namespace std;
int main ()
{
string mystring = "Whats wrong with my string";
return 0;
}
If you write it in the following way, it should work.
It's safer to define strings like I showed it. It will be also easier for you if you add using namespace std in the beginning of every program if you are new to C++.

A strange error when trying to scanf into a global int

Here is the code
#include "stdafx.h"
#include <string>
#include <clocale>
#include <stdio.h>
#include <cstdlib>
using namespace std;
int souls;
void userInput(char situation[20]) {
if (situation == "souls") {
scanf("%i", souls);
printf("%i", souls);
}
}
void main() {
setlocale(LC_CTYPE, "rus");
userInput("souls");
system("pause");
}
It brakes after I input something in my scanf() (trying to change a global int) via the console (int number for example) and drops me into an "unhandled exception"
Why is it so? I am using MS Visual Studio 2005.
In your code
scanf("%i", souls);
should be
scanf("%i", &souls);
^
scanf() needs a pointer to type as the argument to store the scanned value corresponding to the supplied format specifier.
That said, if (situation=="souls") is wrong, too. You cannot compare the contents of strings using the == operator. You need to use strcmp() for that.
Your code has several issues:
You cannot compare C strings this way: if (situation == "souls"): you are comparing the addresses of the char arrays, not their contents. You need to use strcmp (and include <cstring>) for this:
if (!strcmp(situation, "souls"))
The signature void userInput(char situation[20]) is confusing: the size 20 information is ignored and your are actually passing the address of a shorter string literal, this signature would be more appropriate:
void userInput(const char *situation)
You need to pass the address of the output variable to scanf and check the return value: scanf("%i", souls); invokes undefined behavior, it should be changed to:
if (scanf("%i", &souls) == 1) {
/* souls was assigned a value */
} else {
/* scanf failed to parse an integer */
}
The signature for main should not be void main(), it should be either:
int main()
or
int main(int argc, char *argv[])