Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault on linux when easyloggingpp included in several files #117

Closed
alexandrei opened this issue Sep 29, 2013 · 2 comments
Closed

Segfault on linux when easyloggingpp included in several files #117

alexandrei opened this issue Sep 29, 2013 · 2 comments

Comments

@alexandrei
Copy link

Platform: Linux (archlinux, debian)
Compiler: g++ or clang++
Log file location: default configuration
Macros: _ELPP_THREAD_SAFE
Easyloggingpp version: 9.22

Reproduction rate: 100%

Steps:

  1. have two source files (ex: main.cpp ext.cpp)
  2. include in both easylogging++.h
  3. in main.cpp "#define _ELPP_THREAD_SAFE" and _INITIALIZE_EASYLOGGINGPP
  4. have LOG(xx) << "msg"; in both files.
  5. compile and link (see logs below)
  6. run => SEGFAULT

The problem occurs only on linux, I haven't seen it on MinGW32. In this simple example it happens only when "_ELPP_THREAD_SAFE" is defined. In my program it happens even if this is not enable (although there I actually use threads, so I need to have it defined). Please check below backtraces from gdb (for both g++ and clang++)

Thank you,
Alex

Logs with g++:

alex@blackbox ~/logger_investigation> make all                                                                                                       127 master+?
#=========== Cleaning... ===========
rm -rf build/ext.o build/main.o bin/test.exe


#=========== Pre-building... ===========
mkdir -p bin
mkdir -p build

-------- Compiling: src/ext.cpp ----------
g++ -g -std=c++11 -pedantic -Wall  -I/usr/include -I. -Iinclude -Ilib/easyloggingpp/src -c src/ext.cpp -o build/ext.o


-------- Compiling: src/main.cpp ----------
g++ -g -std=c++11 -pedantic -Wall  -I/usr/include -I. -Iinclude -Ilib/easyloggingpp/src -c src/main.cpp -o build/main.o


#=========== Linking... ===========
g++ -g -static-libstdc++ -static-libgcc build/ext.o build/main.o -o bin/test.exe -L/usr/lib -lpthread


#=========== Post-building... ===========
#=========== Testing... ===========

bin/test.exe ./test/f2.JPG
terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_S_create
make: *** [test] Aborted (core dumped)
alex@blackbox ~/logger_investigation> gdb bin/test.exe                                                                                                 2 master+?
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/alex/logger_investigation/bin/test.exe...done.
(gdb) b main
Breakpoint 1 at 0x41fbf2: file src/main.cpp, line 12.
(gdb) run
Starting program: /home/alex/logger_investigation/bin/test.exe 
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
terminate called after throwing an instance of 'std::length_error'
  what():  basic_string::_S_create

Program received signal SIGABRT, Aborted.
0x00007ffff75463d9 in raise () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff75463d9 in raise () from /usr/lib/libc.so.6
#1  0x00007ffff75477d8 in abort () from /usr/lib/libc.so.6
#2  0x000000000045b3e5 in __gnu_cxx::__verbose_terminate_handler() ()
#3  0x00000000004284d6 in __cxxabiv1::__terminate(void (*)()) ()
#4  0x0000000000428503 in std::terminate() ()
#5  0x00000000004264be in __cxa_throw ()
#6  0x0000000000454de7 in std::__throw_length_error(char const*) ()
#7  0x0000000000458d72 in std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) ()
#8  0x000000000045992b in std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) ()
#9  0x0000000000459fac in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&) ()
#10 0x000000000040bd62 in el::Configuration::Configuration (this=0x6d5230, level=@0x482e98: 39832, configurationType=@0x482e9a: el::PerformanceTracking, 
    value=...) at lib/easyloggingpp/src/easylogging++.h:2074
#11 0x000000000040c196 in el::Configurations::unsafeSet (this=0x6d5460, level=@0x482e98: 39832, configurationType=@0x482e9a: el::PerformanceTracking, value=...)
    at lib/easyloggingpp/src/easylogging++.h:2504
#12 0x000000000040c079 in el::Configurations::set (this=0x6d5460, level=@0x482e98: 39832, configurationType=@0x482e9a: el::PerformanceTracking, value=...)
    at lib/easyloggingpp/src/easylogging++.h:2248
#13 0x000000000040c129 in el::Configurations::set (this=0x6d5460, conf=0x482e90 <vtable for el::Configurations+16>) at lib/easyloggingpp/src/easylogging++.h:2260
#14 0x000000000040bfbd in el::Configurations::setFromBase (this=0x6d5460, base=0x6d4360) at lib/easyloggingpp/src/easylogging++.h:2200
#15 0x000000000040deb1 in el::Logger::configure (this=0x6d52c0, configurations=...) at lib/easyloggingpp/src/easylogging++.h:2967
#16 0x000000000040dd19 in el::Logger::Logger (this=0x6d52c0, id=..., configurations=..., logStreamsReference=0x6d4398)
    at lib/easyloggingpp/src/easylogging++.h:2930
#17 0x000000000040e149 in el::base::RegisteredLoggers::get (this=0x6d4320, id=..., forceCreation=true) at lib/easyloggingpp/src/easylogging++.h:3060
#18 0x000000000042196e in el::base::Storage::Storage (this=0x6d4010) at lib/easyloggingpp/src/easylogging++.h:3260
#19 0x00000000004200d2 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at src/main.cpp:3
#20 0x0000000000420136 in _GLOBAL__sub_I__ZN2el4base9elStorageE () at src/main.cpp:17
#21 0x0000000000481ffd in __libc_csu_init ()
#22 0x00007ffff7532b55 in __libc_start_main () from /usr/lib/libc.so.6
#23 0x00000000004090c9 in _start ()

======================================================================

Logs with clang++:

alex@blackbox ~/logger_investigation> make all                                                                                                           master+?
#=========== Cleaning... ===========
rm -rf build/ext.o build/main.o bin/test.exe


#=========== Pre-building... ===========
mkdir -p bin
mkdir -p build

-------- Compiling: src/ext.cpp ----------
clang++ -g -std=c++11 -pedantic -Wall  -I/usr/include -I. -Iinclude -Ilib/easyloggingpp/src -c src/ext.cpp -o build/ext.o


-------- Compiling: src/main.cpp ----------
clang++ -g -std=c++11 -pedantic -Wall  -I/usr/include -I. -Iinclude -Ilib/easyloggingpp/src -c src/main.cpp -o build/main.o


#=========== Linking... ===========
clang++ -g -static-libstdc++ -static-libgcc build/ext.o build/main.o -o bin/test.exe -L/usr/lib -lpthread


#=========== Post-building... ===========
#=========== Testing... ===========

bin/test.exe ./test/f2.JPG
make: *** [test] Segmentation fault (core dumped)
alex@blackbox ~/logger_investigation> gdb bin/test.exe                                                                                                 2 master+?
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/alex/logger_investigation/bin/test.exe...done.
(gdb) b main
Breakpoint 1 at 0x41cb09: file src/main.cpp, line 12.
(gdb) run
Starting program: /home/alex/logger_investigation/bin/test.exe 
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x000000000040a28f in el::base::utils::AbstractRegistry<el::Configuration, std::vector<el::Configuration*, std::allocator<el::Configuration*> > >::operator!= (
    this=0x4d9490, other=...) at lib/easyloggingpp/src/easylogging++.h:1583
1583            if (size() != other.size()) {
(gdb) bt
#0  0x000000000040a28f in el::base::utils::AbstractRegistry<el::Configuration, std::vector<el::Configuration*, std::allocator<el::Configuration*> > >::operator!=
    (this=0x4d9490, other=...) at lib/easyloggingpp/src/easylogging++.h:1583
#1  0x000000000040836e in el::Logger::configure (this=0x4d92f0, configurations=...) at lib/easyloggingpp/src/easylogging++.h:2966
#2  0x0000000000408210 in el::Logger::Logger (this=0x4d92f0, id=..., configurations=..., logStreamsReference=0x4d83a8)
    at lib/easyloggingpp/src/easylogging++.h:2930
#3  0x000000000040811d in el::Logger::Logger (this=0x4d92f0, id=..., configurations=..., logStreamsReference=0x4d83a8)
    at lib/easyloggingpp/src/easylogging++.h:2931
#4  0x0000000000407dd3 in el::base::RegisteredLoggers::get (this=0x4d8330, id=..., forceCreation=true) at lib/easyloggingpp/src/easylogging++.h:3060
#5  0x000000000041e29e in el::base::Storage::Storage (this=0x4d8010) at lib/easyloggingpp/src/easylogging++.h:3260
#6  0x000000000041d8d5 in el::base::Storage::Storage (this=0x4d8010) at lib/easyloggingpp/src/easylogging++.h:3274
#7  0x000000000041d7e8 in __cxx_global_var_init1 () at src/main.cpp:3
#8  0x000000000041d87e in global constructors keyed to a() () at src/main.cpp:645
#9  0x000000000048349d in __libc_csu_init ()
#10 0x00007ffff7532b55 in __libc_start_main () from /usr/lib/libc.so.6
#11 0x0000000000402809 in _start ()
(gdb) 
@easylogging
Copy link
Contributor

Hi Alex,

Thanks for the report - I have successfully reproduced the bug but I can see couple of things wrong here; I am going to list few of them here;

  • You are making thread safe declaration only for the one included from main.cpp, you should do it for both; I have sucessfully compiled and ran program like following
    g++ -g -std=c++11 -pedantic -Wall -I/usr/include -I. -Iinclude -c other.cpp -o other.o -D_ELPP_THREAD_SAFE && g++ -g -std=c++11 -pedantic -Wall -I/usr/include -I. -Iinclude -c main.cpp -o main.o -D_ELPP_THREAD_SAFE && g++ -g -static-libstdc++ -static-libgcc other.o main.o -o test -L/usr/lib -lpthread -D_ELPP_THREAD_SAFE && ./test
    (Notice the -D_ELPP_THREAD_SAFE)
  • If you change the order of linking in make file from other.o main.o to main.o other.o you will get expected result; this is because initialization is done in main.cpp (In this example you don't need _ELPP_THREAD_SAFE defined in makefile but I can't guarantee that it will be thread safe from methods in ext.cpp; in order to do that you should follow the point no. 1
    FROM: g++ -g -std=c++11 -pedantic -Wall -I/usr/include -I. -Iinclude -c other.cpp -o other.o && g++ -g -std=c++11 -pedantic -Wall -I/usr/include -I. -Iinclude -c main.cpp -o main.o && g++ -g -static-libstdc++ -static-libgcc other.o main.o -o test -L/usr/lib -lpthread && ./test
    TO: g++ -g -std=c++11 -pedantic -Wall -I/usr/include -I. -Iinclude -c other.cpp -o other.o && g++ -g -std=c++11 -pedantic -Wall -I/usr/include -I. -Iinclude -c main.cpp -o main.o && g++ -g -static-libstdc++ -static-libgcc main.o other.o -o test -L/usr/lib -lpthread && ./test

Let me know how did you go with your tests and feel free to close this issue if you happy

@alexandrei
Copy link
Author

Hello Majid,

You are right about pt.1 ! It didn't cross my mind I have to "#define" the flags in each file where I include easyloggingpp.h - I was sure that once they are picked up by _INITIALIZE_EASYLOGGINGPP it's not necessary to re-define them anymore.

Now it makes sense, but maybe you could add a section in the readme for noobs like me, regarding this :)

Thank you again for your help and the fast feedback!

Alex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants