When I run the exe application, the code I wrote closes immediately before completion - console-application

I just started learning the C language. I run the exe application, the code I wrote is immediately closed before completion.
I also wrote the getch () command, I don't know what I did wrong. There are no problems in the compiler, the console does not close immediately. However, when I run the exe application, I encounter 2 problems: 1- The code I wrote is not visible on the console, (i.e. after only a part of the code works)
2- console turns off immediately. Please help, I'm about to go crazy!
If you want to look at the exe file:https://mega.nz/#!EzhwCAQb!KOxP1w6GZbT4JoZzOIOltKdEfY03tBZJVvFlrvq-Sqg
#include <stdio.h>
int main() {
printf ("Uyari: Turkce karakter kullanmayiniz ve sorulari tek kelime ile cevaplandiriniz.\n\n");
char isminiz[15];
char soyisminiz[15];
char yasiniz[3];
char mutlu[15];
char sanat[30];
char fb[20];
char kim[20];
printf ("Isminizi yaziniz: ");
scanf("%s",isminiz);
printf ("Soyisminizi yaziniz: ");
scanf ("%s",soyisminiz);
printf ("Yasiniz: ");
scanf("%s",yasiniz);
printf ("Mutluluk nedir: ");
scanf("%s",mutlu);
printf ("Peki sanat nedir desek: ");
scanf("%s",sanat);
printf ("Fb nin uykusu gelmis midir: ");
scanf("%s",fb);
printf ("\nIsim: %s - Soyisim: %s \n",isminiz,soyisminiz);
printf ("Mutluluk: %s\n",mutlu);
printf ("Sanat: %s\n",sanat);
printf ("Gelmis mi: %s\n\n",fb);
printf ("Fb seni cok seviyor dostum hayirli geceler :) \n");
printf("Devam etmek için herhangi bir tuşa basın\n");
getchar();
return 0;
}

Related

Why am I getting a segmentation fault when I use switch-case statement with hash-strings? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I am trying to create a CLI (Command Line Interface). I currently don't have a good idea of what I want from it.
Note: The faults started appearing when I used a switch-case statement with hash-strings to run the commands. Also, there are no errors when compiled. The faults may start anywhere, because I have used printf to print a message representing argc and argv when the cli is run.
Below is the code I used:
codeycat.cpp
#include <map>
#include <iostream>
using namespace std;
static enum Functions {
undef,
comm_test,
comm_commands
} functions;
static map<string, Functions> mapStringValues;
static void Initialize();
bool samestr(const char *svar, const char *str)
{
if (strcmp(svar, str) == 0)
{
return true;
}
else
{
return false;
}
}
string construct_version(int major, int minor, int patch)
{
string strmajor = to_string(major);
string strminor = to_string(minor);
string strpatch = to_string(patch);
string version = strmajor + "." + strminor + "." + strpatch;
return version;
}
int test(string command)
{
int code = system(command.c_str());
return code;
}
void commands()
{
printf("(test, commands)\n");
}
int main(int argc, char *argv[])
{
string doc = "Usage: codeycat [options...] [function] [args...]\n"
"Options:\n"
"\t--help -h: Show this message and exit\n"
"\t--version -v: Show version and exit\n";
string version = construct_version(1, 0, 0);
printf("arg count: %d, args: %s %s %s", argc, argv[0], argv[1], argv[2]);
if (argc < 2)
{
printf("%s", doc.c_str());
return 1;
}
const char command[PATH_MAX] = {*argv[2]};
switch (mapStringValues[command])
{
case undef:
printf("Command not found: %s", command);
case comm_test:
test(argv[3]);
case comm_commands:
cout << "Hello" << endl;
// commands();
}
return 0;
}
void Initialize()
{
mapStringValues["undef"] = undef;
mapStringValues["test"] = comm_test;
mapStringValues["commands"] = comm_commands;
}
Running % ./codeycat of course returns a return code 1 (error), but running % ./codeycat with options --help, --version, -h, -v or running its functions don't work.
Here are the outputs:
./codeycat
arg count: 1, args: ./codeycat (null) COLORTERM=truecolorUsage: codeycat [options...] [function] [args...]
Options:
--help -h: Show this message and exit
--version -v: Show version and exit
./codeycat --help
[1] 12372 segmentation fault ./codeycat --help
./codeycat -h
[1] 12416 segmentation fault ./codeycat -h
./codeycat --version
[1] 12459 segmentation fault ./codeycat --version
./codeycat -v
[1] 12501 segmentation fault ./codeycat -v
./codeycat test 'echo Hello'
[1] 12544 segmentation fault ./codeycat test 'echo Hello'
./codeycat commands
[1] 12587 segmentation fault ./codeycat commands
You can't read from argv without first checking argc. argv is an array of length argc, so any index greater than or equal to argc is out of bounds. This line
printf("arg count: %d, args: %s %s %s", argc, argv[0], argv[1], argv[2]);
Doesn't crash because some printf implementations print "(null)" if you pass a null pointer to the %s specifier.
When you don't pass any arguments, you return early because argc is 1 and you print the doc and return 1.
However, when you do pass an argument, you don't return early, which means you reach this line
const char command[PATH_MAX] = {*argv[2]};
This crashes because you are reading from argv[2] when argc is less than 2. If you pass 2 CLI arguments, this line won't crash. Additionally, this doesn't create a string, it creates an array of size PATH_MAX with element 0 being the first character of argv[2]. If you want to index mapStringValues with argv[2], you need to create an std::string. Also, argv[2] is the second argument, so if you want the first argument to be the command(which is usually the case), then you should read from argv[1].
string command = argv[1];
Switch statement cases don't break automatically, which means that at the end of "case undef:", you will enter "case comm_test".
switch (mapStringValues[command])
{
case undef:
printf("Command not found: %s", command);
// this will fall through to case comm_test,
case comm_test:
test(argv[3]);
case comm_commands:
cout << "Hello" << endl;
// commands();
}
test(argv[3]) will be called even if the initial case is undef.
You need to add break statements to prevent the cases from falling through
switch (mapStringValues[command])
{
case undef:
printf("Command not found: %s", command);
// add break to prevent fallthrough
break;
case comm_test:
test(argv[3]);
break;
case comm_commands:
cout << "Hello" << endl;
break;
// commands();
}
Lastly, you never called Initialize(), so the map is always empty, meaning that every command will result in not being found. You need to call the Initialize() function to initialize the map

error occur when I call execvp to run java

I use chdir() to switch the directory, and then use execvp() to execute "java Main". I'm sure there is Main.class, but something went wrong. I want to know why.
#include <cstdio>
#include <unistd.h>
using namespace std;
int main(){
char buf[80];
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
chdir("/home/keane/Judge/temp");
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
char *array[3];
array[0] = "java";
array[1] = "Main";
array[2] = NULL;
execvp("java", array);
return 0;
}
the error is could not find the main class , and I can run java Main in that directory.
What drives me crazy is that I can't use system("java Main"), and the error is that Error: Could not find or load main class Main, and it's just like this on my computer
update:
#include <unistd.h>
#include <cstdlib>
int main(){
chdir("/home/keane/Judge/temp");
system("pwd");
system("ls");
system("java Main");
return 0;
}
the output on console is:
/home/keane/Judge/temp
1.out 3.out 5.out Main.class stdout_spj.txt
2.out 4.out ce.txt Main.java
Error: Could not find or load the main class Main
my final solution is to reboot the computer and add -cp . to the java command.
althought I don't why is necessary.
thanks everyone!
This works as intended on my system, maybe you need to add -cp . to your java call.
EDIT: to elaborate: -cp (for classpath) tells java where to look for user provided .class files. This does not necessarily include the current working directory by default.
The execution of execvp() is non-blocking and takes ownership of the caller, that means that when it starts if the program ends too quickly you will never be able to see the result, to solve this I use fork(). The wait is just to avoid using sleep as I used at the begining. Its all in c.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char** argv){
char buf[80];
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
chdir("/home/");
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
char *array[3] = {"java", "Main", NULL};
if(fork() == 0) {
if(execvp("java", array) < 0) {
fprintf(stderr, "Error spawning command: %s\n", strerror(errno));
}
} else {
printf("Command spawned\n");
wait(NULL); // Wait to the forked process to end (avoid using sleep)
}
return 0;
}

Linux - segmentation fault only sometimes - how to debug

I have a Linux program, that from time to time ends with a segmentation fault. The program is running periodically every hour, but the segmentation fault occurs only sometimes.
I have a problem to debug this, because if I run the program again with the same input, no error is reported and all is OK.
Is there a way, how to "report" in which part of the code error occured or what caused the problem?
The usual way is to have the crashing program generate a corefile and analyze this after the crash. Make sure, that:
the maximum corefile-size is big enough (i.e. unlimited) by calling ulimit -c unlimited in the shell, which starts the process.
The cwd is writable by the segfaulting process.
Then you can analyze the file with
gdb <exe> <corefile>
Since your code not crashing every time, you can use backtrace as well. Using this you can see the function call stack at the time of crash. There are many examples available. In my projects I normally use the following code for backtracing.
/*
* call reg_usr2 function from main
* gcc -rdynamic myfile.c -o output
*/
#include <stdio.h>
#include <stdarg.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <execinfo.h>
#define FILE_NAME "/tmp/debug"
#define MODE 0xFFFF
void dbgprint(int flag, char* fmt, ...)
{
if(flag & MODE) {
char buf[100];
va_list vlist;
FILE *fp = fopen(FILE_NAME,"a");
va_start(vlist, fmt);
vsnprintf( buf, sizeof( buf), fmt, vlist);
va_end( vlist);
fprintf(fp,"[%x]->%s\n", flag, buf);
fclose(fp);
}
}
/** Here is the code to print backtrace **/
void print_stack_trace ()
{
void *array[20];
size_t size;
char **strings;
size_t i;
size = backtrace (array, 20);
strings = backtrace_symbols (array, size);
dbgprint(0xFFFF, "Obtained %zd stack frames.", size);
dbgprint(0xFFFF, "-------------------------");
dbgprint(0xFFFF, "---------Backtrace-------");
for (i = 0; i < size; i++)
dbgprint (0xFFFF, "%s", strings[i]);
dbgprint(0xFFFF, "-------------------------");
free (strings);
}
void sig_handler(int signo)
{
FILE *fp = fopen(FILE_NAME,"a");
if (signo == SIGUSR2){
dbgprint(0xFFFF, "received SIGUSR2");
dbgprint(0xFFFF, "----------------");
}
print_stack_trace();
exit(0);
}
void reg_usr2()
{
if (signal(SIGUSR2, sig_handler) == SIG_ERR)
printf("\ncan't catch SIGUSR2\n");
}
int main()
{
reg_usr2(); //should be first line of main after variables
//Code.....
return 0;
}
You can generate backtrace by catching SIGSEGV signal, and see where your application throw an invalid access.
see https://stackoverflow.com/a/77336/4490542
But there is more easier solution, try running your application with catchsegv
catchsegv './program args'
and better alternative, valgrind
valgrind --tool=none ./program args

How can a Unix program display output on screen even when stdout and stderr are redirected?

I was running a program (valgrind, actually) on my Ubuntu machine, and had redirected both stdout and stderr to different files. I was surprised to see a short message appear on the screen -- how is that possible? How could I do that myself in a C++ program?
EDIT: Here's the command I used, and the output:
$ valgrind ./myprogram > val.out 2> val.err
*** stack smashing detected ***: ./myprogram terminated
EDIT2: Playing with it a little more, it turns out that myprogram, not valgrind, is causing the message to be printed, and as answered below, it looks like gcc stack smashing detection code is printing to /dev/tty
It is not written by valgrind but rather glibc and your ./myprogram is using glibc:
#define _PATH_TTY "/dev/tty"
/* Open a descriptor for /dev/tty unless the user explicitly
requests errors on standard error. */
const char *on_2 = __libc_secure_getenv ("LIBC_FATAL_STDERR_");
if (on_2 == NULL || *on_2 == '\0')
fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
fd = STDERR_FILENO;
...
written = WRITEV_FOR_FATAL (fd, iov, nlist, total);
Below are some relevant parts of glibc:
void
__attribute__ ((noreturn))
__stack_chk_fail (void)
{
__fortify_fail ("stack smashing detected");
}
void
__attribute__ ((noreturn))
__fortify_fail (msg)
const char *msg;
{
/* The loop is added only to keep gcc happy. */
while (1)
__libc_message (2, "*** %s ***: %s terminated\n",
msg, __libc_argv[0] ?: "<unknown>");
}
/* Abort with an error message. */
void
__libc_message (int do_abort, const char *fmt, ...)
{
va_list ap;
int fd = -1;
va_start (ap, fmt);
#ifdef FATAL_PREPARE
FATAL_PREPARE;
#endif
/* Open a descriptor for /dev/tty unless the user explicitly
requests errors on standard error. */
const char *on_2 = __libc_secure_getenv ("LIBC_FATAL_STDERR_");
if (on_2 == NULL || *on_2 == '\0')
fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
fd = STDERR_FILENO;
...
written = WRITEV_FOR_FATAL (fd, iov, nlist, total);
The message is most probably from GCC's stack protector feature or from glib itself. If it's from GCC, it is output using the fail() function, which directly opens /dev/tty:
fd = open (_PATH_TTY, O_WRONLY);
_PATH_TTY is not really standard, but SingleUnix actually demands that /dev/tty exists.
Here is some sample code that does exactly what was asked (thanks to earlier answers pointing me in the right direction). Both are compiled with g++, and will print a message to the screen even when stdout and stderr are redirected.
For Linux (Ubuntu 14):
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main( int, char *[]) {
printf("This goes to stdout\n");
fprintf(stderr, "This goes to stderr\n");
int ttyfd = open("/dev/tty", O_RDWR);
const char *msg = "This goes to screen\n";
write(ttyfd, msg, strlen(msg));
}
For Windows 7, using MinGW:
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <conio.h>
void writeConsole( const char *s) {
while( *s) {
putch(*(s++));
}
}
int main( int, char *[]) {
printf("This goes to stdout\n");
fprintf(stderr, "This goes to stderr\n");
writeConsole( "This goes to screen\n");
}

Running program through Visual Studio causes it to fail?

I have a problem with a program that I'm writing. It is a command line parser that parses bencode (used in torrent files). The program accepts a filename as it's command line. When I build and run the program in Microsoft Visual Studio 10.0 using the debugging Commmand Line arguments setting to input a command line the program tells me that it failed parsing.
If I open a command prompt and run the program from the command prompt with the same command line, the program works perfectly! What's going on? Is this a common problem with Visual Studio?
I used the debugger in Visual Studio to trace where the program fails and it appears that a call to the stat function ( http://msdn.microsoft.com/en-us/library/14h5k7ff.aspx ) used to get the length of the file returns an error in Visual Studio but works fine when run outside of Visual Studio.
The Code uses a Bencode parser which can be found here: http://funzix.git.sourceforge.net/git/gitweb.cgi?p=funzix/funzix;a=blob;f=bencode/bencode.c
And here is the code for the program:
#include <stdio.h>
#include "../Parse/bencode.h"
int main(int argc, char *argv[]){
if(argc != 2){
printf("Usage: whirlwind filename\n");
return 1;
}
char *buf;
long long len;
be_node *n;
//read the torrent file into a buffer and store at &buf
buf = read_file(argv[1], &len);
if(!buf){
buf = argv[1];
len = strlen(argv[1]);
}
printf("Decoding: %s\n", argv[1]);
n = be_decoden(buf, len);
if(!n){
printf("Parsing failed!\n");
return 1;
}
if(n->type != BE_DICT){
printf("This file is not a valid Bencoded Dictionary.\n");
return 1;
}
int i;
char* keyName;
for(i = 0; i < 10; i++){
keyName = n->val.d[i].key;
if(keyName == "announce"){
printf("\n\n");
}
printf("%s\n", keyName);
if(keyName == "announce"){
printf("\n\n");
}
}
return 0;
}
If you pass a relative path from Visual Studio you should be sure that it resolves correctly when your app runs inside the IDE. This problem arises because, when debugging, the current directory is usually \bin\debug.
To be on the safe side put a full pathname or read the location of your file from a configuration file.