I've a C program as follows:
#include<stdio.h>
void main()
{
printf("Hello");
}
Filename is linkedlist.c
and makefile in the same directory as follows
build: linkedlist.c
gcc -Wall -g -pedantic linkedlist.c -o linkedlist
run:
./linkedlist
I first do M-x compile and then make build followed by M-x compile ->make run which gives output as follows:
-*- mode: compilation; default-directory: "/home/amey/test/" -*-
Compilation started at Sat Sep 22 16:59:13
make run
./linkedlist
Hello make: *** [run] Error 5
Compilation exited abnormally with code 2 at Sat Sep 22 16:59:13
The file generated when ran as ./ gives no error. Can somebody explain what is happening?
Since your main does not return a value or call exit, you are getting a random return code ... in this case, 5 (which happens, not entirely coincidentally, to be the length of "Hello" and the value returned by printf). Since it isn't 0, make interprets it as an error.
To be a conforming C program in a hosted environment, your main must be declared int, and the end of the function much not be reached (without a return statement). The interpretation of the return value is up to the implementation, but usually 0 is considered success and non-0 is considered an error.
Related
I recoded malloc free and realloc in c using mmap and munmap. I compiled them as a shared library .so file.
Here is a simple test:
#include <stdlib.h>
int main() {
int i;
char *addr;
i = 0;
while (i < 1024)
{
addr = (char*)malloc(1024);
addr[0] = 42;
i++;
}
return (0);
}
Here is a run.sh that must replace the stdlib by my shared library:
#/bin/sh
export DYLD_LIBRARY_PATH=.
export DYLD_INSERT_LIBRARIES="libft_malloc.so"
export DYLD_FORCE_FLAT_NAMESPACE=1
$#
The problem is that when i am compiling directly the test file with my shared library and replacing the header in it, it is working well:
-> gcc test1.c libft_malloc.so
-> ./a.out
-> no error
But when i am running it with the run.sh that should just replace the official malloc library by my libft_malloc.so file, i am getting a segfault:
-> gcc test1.c
-> ./run.sh ./a.out
-> ./run.sh: line 5: 73502 Segmentation fault: 11 $#
I know the error is in my code and not in the run.sh or in the test.c because they are the officials files i must use to test my library in my school and those files are working well on other malloc repositories, but i can't find what can be the problem.
Here is my repository: https://github.com/Shirakawa42/malloc.git
I tried debugged by placing write() everywhere but the segfault don't seems to be in the malloc, so i'm lost.
edit:
It also segfault if we run a test without any malloc, but just by loading my library:
#include <stdlib.h>
int main() {
int i;
i = 0;
while (i < 1024)
{
i++;
}
return (0);
}
-> gcc test1.c
-> ./run.sh ./a.out
-> ./run.sh: line 5: 74764 Segmentation fault: 11 $#
edit 2:
Compiling with flag fsanitize=address repair the segfault, but it's absolutely not optimal
edit 3:
Setting the 2 first export manually in shell tell me:
dyld: warning: could not load inserted library 'libft_malloc.so' into library validated process because no suitable image found. Did find:
libft_malloc.so: code signing blocked mmap() of 'libft_malloc.so'
and after setting the third export all my actions make me segfault, like ls and vim, cd made me abort
dyld: warning: could not load inserted library 'libft_malloc.so' into library validated process because no suitable image found. Did find:
libft_malloc.so: code signing blocked mmap() of 'libft_malloc.so'
This error append when there are a segfault in your malloc or free, repairing free made it work.
You can debug it in gdb. First build your code with debug options:
gcc -g -O0
Above options should be used for both your lib and test program. Then you can try running you program in gdb:
gdb a.out
(gdb) r <arguments to a.out>
(gdb) bt <-- when it crashes
Linux loads you program in the memory and calls the entry point main. Startup code that compiler adds for the platform may have calls to malloc. Hence, the crash without malloc in your test code.
Thanks , this has been solved , please see updated code and output in the answer . Thanks Jonathan and everyone else.
I have written below code to read the file present in same directory.
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
int main(){
FILE *fptr;
/*Tried putting different combinations like filename with
quotes|filename without quotes|complete path with quotes|complete path
without quotes*/
if((fptr=fopen("TestFile.txt","r"))==NULL){
printf("\nfopen() returning NULL: %d , %s \n",errno,strerror(errno));
}else{
printf("\nfopen() returning something else: %d , %s
\n",errno,strerror(errno));
}
int c;
while((c=fgetc(fptr))!=EOF){
printf("%c",c);
}}
And i am was getting below output :
./a.out
Segmentation fault (core dumped)
And a GDB core analysis had the following :
(gdb) run
Starting program: /home/astitva/Documents/Coding/a.out
Dwarf Error: wrong version in compilation unit header (is 0, should be 2,
3, or 4) [in module /usr/lib/debug/.build-
id/12/5dab90a4cfa8edc5d532f583e08e810c232cd5.debug]
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
Dwarf Error: wrong version in compilation unit header (is 0, should be 2,
3, or 4) [in module /usr/lib/debug/.build-
id/c0/5201cc642f6b800835e811d7cb28f103aeb191.debug]
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7abc496 in strlen () from /lib/x86_64-linux-gnu/libc.so.6
and my text file TestFile.txt was :
DATA ENETERD AT RUN INSTANCE 1 ------> BLABLABLA
DATA ENETERD AT RUN INSTANCE 2 ------> YADAYADAYADA
DATA ENETERD AT RUN INSTANCE 3 ------> FOOBARFOOBAR
To avoid the warning, you need to #include <string.h> in your code. Add an exit(1) in the error-handling if block :
if((fptr=fopen("TestFile.txt","r"))==NULL){
printf("\nfopen() returning NULL: %d %s\n",errno, strerror(errno));
exit(1);
}
The program needs to exit "gracefully" if the file doesn't exist. So, if there is no valid file present, the program will simply exit and not print anything on the stdout.
EDIT : Just adding on Jonathan's helpful comment on ignoring compiler's warnings :
"If you ignored a compiler warning — don't. If the compiler didn't warn you about the undeclared function strerror(), you need to find the options that make it report such problems (if you use gcc, you would use gcc -Wall -Wextra -Werror — and I'd add -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Wold-style-declaration too, though clang doesn't like -Wold-style-declaration)."
I'm trying to cross compile net-snmp for mips64, and in order to do that I need the libperl library. I tried to configure libperl for mips64 using the following command:
./Configure -Dcc=/home/toby/x-tools/mips64-n64-linux-gnu/bin/mips64-n64-linux-gnu-gcc -Dprefix=/home/toby/perl
But I got the following error:
Checking your choice of C compiler and flags for coherency...
I've tried to compile and run the following simple program:
#include <stdio.h>
int main() { printf("Ok\n"); return(0); }
I used the command:
/home/toby/x-tools/mips64-n64-linux-gnu/bin/mips64-n64-linux-gnu-gcc -o try -O -I/usr/local/include try.c
./try
and I got the following output:
./try: 1: Syntax error: "(" unexpected
The program compiled OK, but exited with status 2.
(The supplied flags or libraries might be incorrect.)
You have a problem. Shall I abort Configure [y]
How can I fix this?
I'd turn:
#include <stdio.h>
int main() { printf("Ok\n"); return(0); }
Into:
#include <stdio.h>
int main() {
printf("Ok\n");
return(0);
}
And then run the compile command by hand to see which line really contains the syntax error.
That looks like an error from your shell and not the compiler. Particularly because gcc doesn't return "status 2" for a syntax error, but bash does. The problem happens because you have cross compiled a program called ./try for mips64. How do you expect ./Configure to execute it on your host pc? – indiv
So I've been trying to get this code to compile using a gcc compiler using c (I found lots of references to c++ but none to c so I asked this) I kept on getting the error Badly placed ()'s every time I go to run the program. So I simplified it to a very simple Hello World test program and I still get the same error.
What could be causing this error?
#include <stdio.h>
int main(int argc, int* argv[])
{
printf("Hello World\n");
return 0;
}
It seems that you are not trying to execute the compiled binary, but that you have a system that runs a tcsh and you are feeding the C source code directly into that shell:
> tcsh /tmp/badly.c
Badly placed ()'s.
A C program must first be compiled to a binary (here: /tmp/badly), and then you have to execute that binary:
> gcc /tmp/badly.c -Wall -o /tmp/badly
/tmp/badly.c:3:5: warning: second argument of 'main' should be 'char **' [-Wmain]
> /tmp/badly
Hello World
As ouah already noticed in his answer, with the -Wall argument to gcc you also get the informative message that the parameters of your main function are wrong.
I'm compiling the below C code with gcc. No errors are thrown during compilation or at runtime. I ran through the code with gdb, and the answer given in sum is correct at the end, yet the printf() does not display anything on the screen. I've tried all sorts of combinations of fprintf(), printf(), and fflush(), but nothing works.
What do I need to change so the program will print the result to stdout?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num = 9;
int i, sum; i = 1, sum = 0;
while (i < 2 * num) {
sum = sum + i * i;
++i;
}
printf("sum: %d\n", sum);
fflush(stdout);
return 0;
}
The code is correct, and should print sum: 1785 for any conforming implementation.
This is a guess (update: which turns out to be correct), but ...
You've named the source file test.c, and you compile it with:
$ gcc test.c -o test
(or something similar) and execute it with:
$ test
which produces no output.
The problem is that test is a standard Unix command (and also a built-in command in some shells). When you type a command name to the shell, it first looks for built-in commands, then for executables in directories specified in your $PATH environment variable.
To execute a command in the current directory, prepend ./ to the name:
$ ./test
sum: 1785
$
This applies to any command in the current directory. There are so many built-in commands that you can't reasonably avoid colliding with them. Cultivating the habit of running executables in the current directory by typing ./whatever means that name collisions don't matter.
(Don't be tempted to add . to the front of your $PATH; that's dangerous. Think about what could happen if you cd into a directory and type ls, if there happens to be a malicious ls command there.)
There is nothing wrong with your program. It has to work. Try running it with redirection:
./a.out > myout
..and see if you get any output. If not, I'd suspect there is a problem with some kind of standard library mismatch.
Another option to check would be to build using SUN C compiler as opposed to gcc and see if that works. If it does, gcc is the culprit.