Is there any chance to disable the terminal color output of Asan? No matter which flags I pass, it prints terminal color codes:
Heap left redzone: [1m[31mfa[1m[0m
Freed heap region: [1m[35mfd[1m[0m
Stack left redzone: [1m[31mf1[1m[0m
Stack mid redzone: [1m[31mf2[1m[0m
Stack right redzone: [1m[31mf3[1m[0m
Stack partial redzone: [1m[31mf4[1m[0m
Stack after return: [1m[35mf5[1m[0m
The arguments I tried out:
clang++ -fsanitize=address -fno-color-diagnostics ...
clang++ -fsanitize=address -fcolor-diagnostics=never ...
clang++ -fsanitize=address -fdiagnostics-color=never ...
What do I miss? Is there maybe an API I can use to turn it off?
Add the entry color=never to the environment variable ASAN_OPTIONS:
$ clang++-3.6 -O -g -fsanitize=address test.cpp
$ ASAN_OPTIONS="color=never" ./a.out
Related
When debugging my big rust project, I face a problem that gdb set break point at incorrect line number.
When I type command to set break point at line 406
break <absolute-path-of-my-file>/lib.rs:406
it return that break point is created at line 432
Breakpoint 2 at 0x5555570b9395: file <absolute-path-of-my-file>/lib.rs, line 432.
When I check code at line number 406
list <absolute-path-of-my-file>/lib.rs:406
It return
file: "<absolute-path-of-my-file>/lib.rs", line number: 406, symbol: "???"
My question is:
Why did it set break at line 432 when I created break at line 406?
What does symbol: "???" mean in the list command return? Thanks for any help!
PS: Size of binary file (after build without optimization) is 22 GB, larger than my memory (16GB)
#Phùng Hưng Thịnh
When I compile C/C++ program, I used to use following to debug my program.
g++ -g -Wall source.C
g++ -g -Wall source.CPP
g++ -g -Wall source.c
g++ -g -Wall source.cpp
For debugging I never use the following during compilation:
-O0
Also I used to use:
ulimit -c unlimited
to know if program creating any core dump or not?
If we are using dynamic library(.dll/.so/.sl on any platform windows/Linux/AIX/SunOS/HP-UX/OSF1/IRIX/UNIX) and providing break point to a function inside that external library, that may show ??? output.
If you are providing break to a function inside dynamic library the line numbers will provide the line number where you are invoking that external function from external library.
I have given the sample usage of gdb using C C++ program, related compilation options and external dependencies at any operating systems.
I tried following commands at Linux and "CYGWIN_NT" at windows using gdb:
$ gdb
(gdb) !ls -d .
.
(gdb) quit
Hence can you provide the output for:
(gdb) !ls "<absolute-path-of-my-file>/lib.rs"
GNU DEBUGGER(GDB) usage at Rust
Make sure there is a rust-gdb executable
Use rust-gdb to debug rustc executable.
All my previous comments based only on C and C++ programming not at rust-gdb.
Actually I don't have rust/... debugger at my system.
I have only C C++ compiler and debugger here.
Example C Code:
#include <stdio.h>
void fun()
{
printf( "fun\n");
}
int main()
{
fun();
return 0;
}
Example gdb.exe usage:
$ gcc.exe -g -Wall sample.c -o ./a.out
Exampe gdb
$ gdb.exe -q ./a.out
Reading symbols from ./a.out...
(gdb) break fun
Breakpoint 1 at 0x100401088: file sample.c, line 4.
(gdb) run
Starting program: /cygdrive/c/home/murugesan_openssl/a.out
[New Thread 6108.0xc88]
[New Thread 6108.0x2428]
[New Thread 6108.0x12b8]
Thread 1 "a.out" hit Breakpoint 1, fun () at sample.c:4
4 printf( "fun\n");
(gdb) list
1 #include <stdio.h>
2 void fun()
3 {
4 printf( "fun\n");
5 }
6 int main()
7 {
8 fun();
9 return 0;
10 }
(gdb) quit
A debugging session is active.
Inferior 1 [process 6108] will be killed.
Quit anyway? (y or n) y
Example to print code:
$ gdb -q ./a.out
Reading symbols from ./a.out...
(gdb) break fun
Breakpoint 1 at 0x100401088: file sample.c, line 4.
(gdb) list sample.c:4
1 #include <stdio.h>
2 void fun()
3 {
4 printf( "fun\n");
5 }
6 int main()
7 {
8 fun();
9 return 0;
10 }
(gdb) quit
This question already has answers here:
Where are GDB symbols coming from?
(2 answers)
Closed 3 years ago.
On Fedora 31, I see that gdb knows the symbols of some system binaries, e.g. main of /usr/bin/true:
$ gdb -ex 'set height 0' -ex 'disas main' -ex q /bin/true
Reading symbols from /bin/true...
Reading symbols from .gnu_debugdata for /usr/bin/true...
(No debugging symbols found in .gnu_debugdata for /usr/bin/true)
Dump of assembler code for function main:
0x0000000000002550 <+0>: endbr64
0x0000000000002554 <+4>: cmp edi,0x2
[..]
But main doesn't show up in objdump -d nor `nm output:
$ objdump -d /usr/bin/true | grep '\<main\>'
$ nm /usr/bin/true | grep main
nm: /usr/bin/true: no symbols
$ nm -D /usr/bin/true | grep '\<main\>'
$
How come? Is gdb able to read the main symbol from some additional symbol table?
When I compile my own binaries with gcc, nm/objdump show the main symbol as expected. Also, when I strip such a binary, gdb can't find the main symbol, as well.
I assume that rpmbuild calls gcc/strip with some special flags that cause the above behavior. What are those?
Is gdb able to read the main symbol from some additional symbol table?
Yes: the one contained in the .gnu_debugdata section. More info here.
gdb also prints: No debugging symbols found in .gnu_debugdata for /usr/bin/true
GDB says: there are no debugging symbols (i.e. ones with file/line info, variable info, etc.). It doesn't say "there are no symbols" (i.e. things you would see in nm output). In fact, symbols are raison d'etre for .gnu_debugdata in the first place.
I've done a bunch of reading on dynamic linker relocations and position independent code including procedure linkage tables and global offset tables. I don't understand why a statically linked executable needs a PLT and GOT. I compiled a hello world program on my ubuntu x86_64 machine and when I dump the section headers with readelf -S it shows PLT and GOT sections.
I also created a shared library with a simple increment function that I compiled with gcc -shared without -fpic and I also see PLT and GOT sections. I didn't expect this either.
I don't understand why a statically linked executable needs a PLT and GOT.
It doesn't.
I compiled a hello world program on my ubuntu x86_64 machine and when I dump the section headers with readelf -S it shows PLT and GOT sections.
This is an accident of implementation. The sections come from crt1.o, and there isn't a separate crt1s.o for fully-static linking, so you end up with .plt and .got entries from there.
You can strip these sections, and the binary will still work:
objcopy -R.got -R.plt a.out a.out2
Note: do not strip .rela.plt, as that section is still needed to implement IFUNCs.
I found that gcc generates a .got and .got.lpt when generating position independent code and taking the address of a function defined in another source file.
My test files were:
part1.c:
extern void afunc();
int _start()
{
return 0x55 & (__SIZE_TYPE__) afunc;
}
part2.c:
void afunc() {}
My test was (substitute your own gcc version):
for o in s 4 3 2 1 0
do
aarch64-linux-gnu-gcc-10 -fPIC part1.c part2.c -o static.elf -static -nostdlib -O$o &&
aarch64-linux-gnu-objdump -x static.elf | grep 'GLOBAL_OFFSET'
done
I get the following output for all optimization levels:
0000000000410fd8 l O .got 0000000000000000 _GLOBAL_OFFSET_TABLE_
Replacing -fPIC with -fno-PIC and the segment goes away.
You can tell if your compiler defaults to -fPIC by running this:
aarch64-linux-gnu-gcc-10 -mcmodel=large -x c - < /dev/null
From which, I get the error, if it does:
cc1: sorry, unimplemented: code model ‘large’ with ‘-fPIC’
I have just shifted to ubuntu and newly using gdb and g++ . Please forgive me if my question is silly .
This is from Richard Stevens Advanced Linux Programming . Three files were created in the folder names reciprocal
main.c:
#include <stdio.h>
#include "reciprocal.hpp"
int main (int argc, char **argv)
{
int i;
i = atoi (argv[1]);
printf ("The reciprocal of %d is %g\n", i, reciprocal (i));
return 0;
}
reciprocal.cpp:
#include <cassert>
#include "reciprocal.hpp"
double reciprocal (int i) {
// I should be non-zero.
assert (i != 0);
return 1.0/i;
}
reciprocal.hpp:
#ifdef __cplusplus
extern "C" {
#endif
extern double reciprocal (int i);
#ifdef __cplusplus
}
#endif
After compiling , I ran the command (gdb) reciprocal and the (gdb) run . I was expecting something as in the book
Starting program: reciprocal
Program received signal SIGSEGV, Segmentation fault.
__strtol_internal (nptr=0x0, endptr=0x0, base=10, group=0)
at strtol.c:287
287 strtol.c: No such file or directory.
(gdb)
But I got :
Starting program: /home/trafalgar/Desktop/reciprocal/reciprocal
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
Program received signal SIGSEGV , Segmentation fault.
0x00007ffff7a56ad4 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
What might be happening different . Is this a version problem or anything else ?
Here is the Makefile
reciprocal: main.o reciprocal.o
g++ $(CFLAGS) -o reciprocal main.o reciprocal.o
main.o: main.c reciprocal.hpp
gcc $(CFLAGS) -c main.c
reciprocal.o: reciprocal.cpp reciprocal.hpp
g++ $(CFLAGS) -c reciprocal.cpp
clean:
rm -f *.o reciprocal
How did you compile the program?
use g++ -g programname.c
also, when you do
gdb reciprocal
note if there is a message like
loaded symbols from ...
or
couldnot find symbols
if you get output similar to 2nd code statement, then the problem is that you did not use -g symbol.
You should compile with all warnings and debug info, i.e.
gcc -Wall -g -c main.c
g++ -Wall -g -c reciprocal.cpp
then link with
g++ -g main.o reciprocal.o -o reciprocal
So add
CFLAGS= -Wall -g
in your Makefile. See also this.
Then run the debugger with
gdb reciprocal
then set a program argument with set args 12 command to (gdb) prompt
at last start the debugged program with run when having the (gdb) prompt
Of course, if you don't have any program arguments, argc is 1 and argv[1] is NULL, which you should not pass to atoi(3).
The debugger works quite well. The bug is in your code. You should handle correctly the case when argc is 1 and argv[1] is NULL.
If you encounter a segmentation fault inside a C library function, use the bt or backtrace gdb command to understand how you get there.
Everything is working properly, with expected output.
Compare:
1. Starting program: reciprocal
2. Program received signal SIGSEGV, Segmentation fault.
3. __strtol_internal (nptr=0x0, endptr=0x0, base=10, group=0)
4. at strtol.c:287
5. 287 strtol.c: No such file or directory.
A. Starting program: /home/trafalgar/Desktop/reciprocal/reciprocal
B. warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
C. Program received signal SIGSEGV , Segmentation fault.
D. 0x00007ffff7a56ad4 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
Lines 1-5 are your expected output (from Mr Stevens' text), lines A-D are your actual output.
Lines 1 & A, are essentially identical, they both specify the filename of the executable, (1) is relative pathed, (A) has full path. No worries.
Line B... this is NORMAL, this is gdb telling you that you don't have the debugging information installed for your library functions (NOT YOUR CODE, the dynamically linked libraries on your system).
Line C... Same as (2), easy enough.
Line D... Well, since we don't have debug info for the library functions, it can only point out where the error was as best it can: libc.so.6 (standard library functions, of which strtol is one such)
Essentially, line D is similar to lines 3-5. Without the debug information installed/available, you're not going to get much more information than this.
But everything is working as expected. You're fine.
For help on how to install debug symbols, see here: how-to-use-debug-libraries-on-ubuntu
Fear not! You're doing great. (Technically, the error is on line 6 of your main.cpp, since argv[1] is pretty much undefined because you didn't supply an argument, perhaps confusing since atoi() is often replaced with strtol() behind the scenes.)
Try:
gdb --args ./reciprocal 15
or similar to test with arguments.
This question is related to this one as well as its answer.
I just discovered some ugliness in a build I'm working on. The situation looks somewhat like the following (written in gmake format); note, this specifically applies to a 32-bit memory model on sparc and x86 hardware:
OBJ_SET1 := some objects
OBJ_SET2 := some objects
# note: OBJ_SET2 doesn't get this flag
${OBJ_SET1} : CCFLAGS += -PIC
${OBJ_SET1} ${OBJ_SET2} : %.o : %.cc
${CCC} ${CCFLAGS} -m32 -o ${#} -c ${<}
obj1.o : ${OBJ_SET1}
obj2.o : ${OBJ_SET2}
sharedlib.so : obj1.o obj2.o
obj1.o obj2.o sharedlib.so :
${LINK} ${LDFLAGS} -m32 -PIC -o ${#} ${^}
Clearly it can work to mix objects compiled with and without PIC in a shared object (this has been in use for years). I don't know enough about PIC to know whether it's a good idea/smart, and my guess is in this case it's not needed but rather it's happening because someone didn't care enough to find out the right way to do it when tacking on new stuff to the build.
My question is:
Is this safe
Is it a good idea
What potential problems can occur as a result
If I switch everything to PIC, are there any non-obvious gotchas that I might want to watch out for.
Forgot I even wrote this question.
Some explanations are in order first:
Non-PIC code may be loaded by the OS into any position in memory in [most?] modern OSs. After everything is loaded, it goes through a phase that fixes up the text segment (where the executable stuff ends up) so it correctly addresses global variables; to pull this off, the text segment must be writable.
PIC executable data can be loaded once by the OS and shared across multiple users/processes. For the OS to do this, however, the text segment must be read-only -- which means no fix-ups. The code is compiled to use a Global Offset Table (GOT) so it can address globals relative to the GOT, alleviating the need for fix-ups.
If a shared object is built without PIC, although it is strongly encouraged it doesn't appear that it's strictly necessary; if the OS must fix-up the text segment then it's forced to load it into memory that's marked read-write ... which prevents sharing across processes/users.
If an executable binary is built /with/ PIC, I don't know what goes wrong under the hood but I've witnessed a few tools become unstable (mysterious crashes & the like).
The answers:
Mixing PIC/non-PIC, or using PIC in executables can cause hard to predict and track down instabilities. I don't have a technical explanation for why.
... to include segfaults, bus errors, stack corruption, and probably more besides.
Non-PIC in shared objects is probably not going to cause any serious problems, though it can result in more RAM used if the library is used many times across processes and/or users.
update (4/17)
I've since discovered the cause of some of the crashes I had seen previously. To illustrate:
/*header.h*/
#include <map>
typedef std::map<std::string,std::string> StringMap;
StringMap asdf;
/*file1.cc*/
#include "header.h"
/*file2.cc*/
#include "header.h"
int main( int argc, char** argv ) {
for( int ii = 0; ii < argc; ++ii ) {
asdf[argv[ii]] = argv[ii];
}
return 0;
}
... then:
$ g++ file1.cc -shared -PIC -o libblah1.so
$ g++ file1.cc -shared -PIC -o libblah2.so
$ g++ file1.cc -shared -PIC -o libblah3.so
$ g++ file1.cc -shared -PIC -o libblah4.so
$ g++ file1.cc -shared -PIC -o libblah5.so
$ g++ -zmuldefs file2.cc -Wl,-{L,R}$(pwd) -lblah{1..5} -o fdsa
# ^^^^^^^^^
# This is the evil that made it possible
$ args=(this is the song that never ends);
$ eval ./fdsa $(for i in {1..100}; do echo -n ${args[*]}; done)
That particular example may not end up crashing, but it's basically the situation that had existed in that group's code. If it does crash it'll likely be in the destructor, usually a double-free error.
Many years previous they added -zmuldefs to their build to get rid of multiply defined symbol errors. The compiler emits code for running constructors/destructors on global objects. -zmuldefs forces them to live at the same location in memory but it still runs the constructors/destructors once for the exe and each library that included the offending header -- hence the double-free.