In the context of a tool comparison, I do not want to be unfair to ASan if it can detect the problem in the program below:
$ cat t.c
#include <stdio.h>
int *G;
int f(void) {
int l = 1;
int res = *G;
G = &l;
return res + *G;
}
int main(void) {
int x = 2;
G = &x;
f();
printf("%d\n", f());
}
$ clang -v
clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
...
$ clang -O2 -fsanitize=address t.c
$ ./a.out
1
$ clang -fsanitize=address t.c
$ ./a.out
2
The first occurence of G the second time f is called invokes undefined behavior, because G is indeterminate at that point. In addition, G is immediately dereferenced, making this the sort of memory error that one may expect ASan to detect. It is part of ASan's specifications that it sometimes fails to detect problems of the kind it is supposed to find, but I want to know if I could have used it to find this particular problem here.
I found the option -fsanitize-address-use-after-scope here, but this option does not work in the version of Clang I am using:
$ clang -fsanitize=address t.c -fsanitize-address-use-after-scope
clang: error: unknown argument: '-fsanitize-address-use-after-scope'
Is there an ASan version that flags an error at the execution of the above program, with or without special commandline options?
You are talking about use-after-return errors here. These should be supported by ASan but disabled by default due to significantly higher memory overhead (see e.g. here for details). To enable, run with ASAN_OPTIONS=detect_stack_use_after_return=1.
Unfortunately I can't check whether it works on your particular case but if it doesn't, you should probly file a bug at ASan's tracker.
yugr has pointed me to the correct way to activate detection of the error in my test program. This functionality already exists in Clang 3.8.
For completeness, the results with Clang 3.8 are below. It is interesting that the issue is detected at the default optimization level but is not detected at -O2.
$ clang -fsanitize=address t.c -Wall
$ ASAN_OPTIONS=detect_stack_use_after_return=1 ./a.out
=================================================================
==21949==ERROR: AddressSanitizer: stack-use-after-return on address 0x7f5eeb100060 ...
READ of size 4 at 0x7f5eeb100060 thread T0
...
$ clang -O2 -fsanitize=address t.c -Wall
$ ASAN_OPTIONS=detect_stack_use_after_return=1 ./a.out
1
Your version: clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
Header of page: Clang 5 documentation
You have to update your clang
Related
I have a function in my C code that is being called implicitly, and getting dumped by the linker. how can I prevent this phenomena?
I'm compiling using gcc and the linker flag -gc-sections, and I don't want to exclude the whole file from the flag. I tried using attributes: "used" and "externally_visible" and neither has worked.
void __attribute__((section(".mySec"), nomicromips, used)) func(){
...
}
on map file I can see that the function has compiled but didn't linked. am I using it wrong? is there any other way to do it?
You are misunderstanding the used attribute
used
This attribute, attached to a function, means that code must be emitted for the function even if it appears that the function is not referenced...
i.e the compiler must emit the function definition even the function appears
to be unreferenced. The compiler will never conclude that a function is unreferenced
if it has external linkage. So in this program:
main1.c
static void foo(void){}
int main(void)
{
return 0;
}
compiled with:
$ gcc -c -O1 main1.c
No definition of foo is emitted at all:
$ nm main1.o
0000000000000000 T main
because foo is not referenced in the translation unit, is not external,
and so may be optimised out.
But in this program:
main2.c
static void __attribute__((used)) foo(void){}
int main(void)
{
return 0;
}
__attribute__((used)) compels the compiler to emit the local definition:
$ gcc -c -O1 main2.c
$ nm main2.o
0000000000000000 t foo
0000000000000001 T main
But this does nothing to inhibit the linker from discarding a section
in which foo is defined, in the presence of -gc-sections, even if foo is external, if that section is unused:
main3.c
void foo(void){}
int main(void)
{
return 0;
}
Compile with function-sections:
$ gcc -c -ffunction-sections -O1 main3.c
The global definition of foo is in the object file:
$ nm main3.o
0000000000000000 T foo
0000000000000000 T main
But after linking:
$ gcc -Wl,-gc-sections,-Map=mapfile main3.o
foo is not defined in the program:
$ nm a.out | grep foo; echo Done
Done
And the function-section defining foo was discarded:
mapfile
...
...
Discarded input sections
...
...
.text.foo 0x0000000000000000 0x1 main3.o
...
...
As per Eric Postpischil's comment, to force the linker to retain
an apparently unused function-section you must tell it to assume that the program
references the unused function, with linker option {-u|--undefined} foo:
main4.c
void __attribute__((section(".mySec"))) foo(void){}
int main(void)
{
return 0;
}
If you don't tell it that:
$ gcc -c main4.c
$ gcc -Wl,-gc-sections main4.o
$ nm a.out | grep foo; echo Done
Done
foo is not defined in the program. If you do tell it that:
$ gcc -c main4.c
$ gcc -Wl,-gc-sections,--undefined=foo main4.o
$ nm a.out | grep foo; echo Done
0000000000001191 T foo
Done
it is defined. There's no use for attribute used.
Apart from -u already mentioned here are two other ways to keep the symbol using GCC.
Create a reference to it without calling it
This approach does not require messing with linker scripts, which means it will work for hosted programs and libraries using the operating system's default linker script.
However it varies with compiler optimization settings and may not be very portable.
For example, in GCC 7.3.1 with LD 2.31.1, you can keep a function without actually calling it, by calling another function on its address, or branching on a pointer to its address.
bool function_exists(void *address) {
return (address != NULL);
}
// Somewhere reachable from main
assert(function_exists(foo));
assert(foo != NULL); // Won't work, GCC optimises out the constant expression
assert(&foo != NULL); // works on GCC 7.3.1 but not GCC 10.2.1
Another way is to create a struct containing function pointers, then you can group them all together and just check the address of the struct. I use this a lot for interrupt handlers.
Modify the linker script to keep the section
If you are developing a hosted program or a library, then it's pretty tricky to change the linker script.
Even if you do, its not very portable, for example gcc on OSX does not actually use the GNU linker since OSX uses the Mach-O format instead of ELF.
Your code already shows a custom section though, so it's possible you are working on an embedded system and can easily modify the linker script.
SECTIONS {
// ...
.mySec {
KEEP(*(.mySec));
}
}
Why does this not work?:
prog.c file
#include <stdio.h>
int main(void)
{
int i, j;
printf("\n%d\n%d\n", i, j);
return 0;
}
debug file:
#!/bin/bash
g++ -Wall -Wextra -Wpedantic -O0 -g3 -fsanitize=address -o temp/debug.out src/prog.c
./temp/debug.out
running:
./debug
prog.c: In function ‘main’:
prog.c:6:9: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
printf("\n%d\n%d\n", i, j);
^~~~~~~~~~~~~~~~~~~~~~~~~~
prog.c:6:9: warning: ‘j’ is used uninitialized in this function [-Wuninitialized]
0
0
==90==LeakSanitizer has encountered a fatal error
==90==HINT: For debugging, try setting environment variable LSAN_OPTION=verbosity=1:log_threads=1
==90==LeakSanitizer does not work under ptrace (strace, gdb, etc)
I'm new to using debuging tools but there isn't much to read on this topic except man pages of compilers. So please can someone help me?
This was executed on Windows 10 subsystem for linux (Ubuntu) on freshly openned terminal.
I'd like to use -fno-sanitize=all option I found in man pages of gcc but it doesn't seem to say a word on any mistake I came up with.
I found out it was problem of WSL i used (I didn't think it was important to say i use one)
Turns out i need to write LSAN_OPTION=verbosity=1:log_threads=1; g++ -Wall...
I'm trying to implement a simple integration of R with C. Initially it's simple: I want to pass values from R to a C function built into a .o shared library via .C or .Call function. The C function should simply print the values passed in via printf.
Here's my .Call method:
.Call("test", as.integer(5), as.character("A"), as.character("string_test"))
And my C code:
#include <stdio.h>
void test(int integer, char character, char **str) {
printf("Integer: %i\nChar: %c\nString: %s\n", integer, character, *str);
}
But when I call the C function from R via console (RStudio crashes) with gdb enabled, I receive:
Integer: 1466480376
Char: �
Float: -100407552.000000
String:
***caught segfault ***
address 0x20000090, cause 'memory not mapped'
Traceback:
1: .Call("test", as.integer(5), as.character("A"), as.character("string_test"))
As if it were not enough, as we can see the values passed in are printed very strangely.
Details of what I did, step by step:
I built the .o shared library with gcc:
gcc -shared -o func_teste.o -fPIC func_teste.c
And prepared it for dynamic loading in R environment:
$ R CMD SHLIB func_teste.o
gcc -m64 -I/usr/include/R -DNDEBUG -I/usr/local/include -fpic -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic -c func_teste.c -o func_teste.o
gcc -m64 -shared -L/usr/lib64/R/lib -Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -o func_teste.so func_teste.o -L/usr/lib64/R/lib -lR
And finally, inside R console, i ran:
>dyn.load('func_teste.o')
>.Call("test", as.integer(5), as.character("A"), as.character("string_test"))
Does anyone have idea why this is happening?
R offers two main functions for interfacing from C code (and hence C++ code, or any other language able to use a C interface):
- .C() is the older interface using int*, double*, ... and alike
- .Call() is the newer, more powerful interface using SEXP objects
Now, .Call() looks more complicated but it is so much more powerful as well as safer. There is near universal consensus that .C() should no longer be used (see various discussions on the r-devel list and other places).
The main downside with .Call() is that you need to learn how to pack and unpack your values. Or ... you cheat and let Rcpp do it for you. So with that, here is one-line solution of the OP's example:
> library(Rcpp)
> cppFunction("void mytest(int i, char c, std::string str) { printf(\"Integer: %i Char: %c String: %s\\n\", i, c, str.c_str()); }")
> mytest(42L, 'Q', "a boat")
Integer: 42 Char: Q String: a boat
>
I made the char* a string. Note that cppFunction() requires escaping of strings, you may want to look into sourceCpp() and packages for real work. The Rcpp documentation has details.
Don't as.character on "string_test".
Read more here: http://mazamascience.com/WorkingWithData/?p=1067
I am trying to compile a simple code with gcc and clang. the gcc generates a warning for an incomparable casting (great!). However, clang didn't generate any warnings! I have passed the same arguments for both:
cc -Wall -Wextra tmp3.c
gcc -Wall -Wextra tmp3.c
Am I passing all the necessary options to clang compiler or missing something? The clang documentation isn't a great help!
Code:
int main(void)
{
void *b = (void *)0x12345678;
int a = (int)(unsigned long)b;
int c = (int)b;
return a + c;
}
Clang version 3.8
I have reached out to the clang developers (mailing list). I have got this response:
In C++ mode, Clang errors on the line, same as everyone else. In C
mode, however, conversions are typically more permissive. In this
case, I suspect Clang should generate this warning as well. It’ll
likely require a patch however.
I was reading C programming from a book that says all variables have to be declared in the beginning of the function. I tried following code but didn't issue any error. I am using mingw and codeblocks. The code is as follows:
#include <stdio.h>
int main()
{
int i=10;
printf("%d\n",i);
int j=20;
printf("%d\n",j);
return 0;
}
Do I have to change any compiler setting or something to make it compatible with the standard given in the book?
I am using -std=c89 compiler option. See the compilation messages below:
-------------- Clean: Debug in HelloWorld (compiler: GNU GCC Compiler)---------------
Cleaned "HelloWorld - Debug"
-------------- Build: Debug in HelloWorld (compiler: GNU GCC Compiler)---------------
mingw32-gcc.exe -Wall -std=c89 -g -c D:\MyCodeBlocksProjects\HelloWorld\main.c -o obj\Debug\main.o
mingw32-g++.exe -o bin\Debug\HelloWorld.exe obj\Debug\main.o
Output size is 68.53 KB
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 0 warnings (0 minutes, 0 seconds)
all variables have to be declared in the beginning of the function.
To be precise, they have to be declared in the beginning of a block. And this is only true in C89. C99 has removed this limit. So you can change your compiler to strict C89 mode. For example, for GCC, it's -std=c89 option. To obtain all the diagnostics required by the standard, you should also specify the option -pedantic.
To demonstrate what I mean by in the beginning of a block, this is legal C89 syntax:
void foo()
{
int x = 1;
x = x + 1;
{
int y = 42; /**OK: declaration in the beginning of a block*/
}
}