Comments (30)
Well, this stuff is hard. I learned something from your StackOverflow question as well. Thanks!
from graylog-logger.
Yes I do. The solution is for me to get around to writing the code documentation. 😃
When you add a new handler using Log::AddLogHandler()
, you loose ownership of the pointer to that handler. I can not say exactly what is happening (and I am pretty sure the behavior is undefined) but it is caused by the library trying to de-allocate the handler after you already having done it once.
If you want to delete a handler manually, you should instead call Log::RemoveAllHandlers()
, which of course will delete all handlers currently in use by the library.
from graylog-logger.
Hm, I took a closer look at what happens when exiting using Ctrl-C and I was wrong. The destructor for the logging library is not called. Regardless, you should not delete a handler used by the logging library.
With that said, I should probably add a Shutdown()
function for cleanly shutting down the logging system when using signal handling functions.
from graylog-logger.
Ah, I was wondering, because I did try using Log::RemoveAllHandlers()
but it didn't work either.
If you need any help developing the destruct/shutdown functionality, please let me know.
from graylog-logger.
Did it not work in that using Log::RemoveAllHandlers()
produced the same error message or did it not work in some other way?
from graylog-logger.
I tried this, but it produced the same error.
void GrayLogging::close()
{
Log::RemoveAllHandlers();
delete handler;
}
from graylog-logger.
When calling Log::AddLogHandler(handler);
the library takes over ownership of the pointer and you should thus not use delete
on that handler as this is done by the library when exiting (or calling Log::RemoveAllHandlers()
). Thus, try the following instead:
void GrayLogging::close()
{
Log::RemoveAllHandlers();
}
from graylog-logger.
Ok, I'm going to try this when I'm home, I'll give you an update when I tested it.
from graylog-logger.
@SkyToGround I tested it but unfortunately it didn't work. I'm getting the same error.
terminate called after throwing an instance of 'std::system_error'
what(): Resource deadlock avoided
Abort (core dumped)
from graylog-logger.
Ok, seeing as I do not see this problem in my own applications it is kind of hard to reproduce. Can you send me an example application which triggers this error and tell me under what system it does so?
from graylog-logger.
Come to think of it, I do have an idea of what is happening but I can not be sure without knowing how your application handles a shutdown. One solution is probably to remove the last call to Log::RemoveAllHandlers();
entirely. You probably do not need it as such. If the application does a clean shutdown, all the handlers will be removed automatically. If it does not, then you will drop objects without proper deallocation anyway.
from graylog-logger.
So based on what I was thinking, I slapped together a simple application which uses std::atexit()
to call Log::RemoveAllHandlers();
. It turns out that at that point, the static logging object (Log::Logger
) has already been deallocated which then causes the application to crash.
from graylog-logger.
@SkyToGround Ok, nice! I've got some time to work on this tomorrow. I'll try and see if I can create an example app that crashes.
from graylog-logger.
@SkyToGround I created an example that crashes on CTRL+C (tested on FreeBSD). I also attached the full backtrace from gdb.
Backtrace when using Log::RemoveAllHandlers();
:
#0 0x000000080156b35a in thr_kill () from /lib/libc.so.7
No symbol table info available.
#1 0x000000080156b346 in raise () from /lib/libc.so.7
No symbol table info available.
#2 0x000000080156b2c9 in abort () from /lib/libc.so.7
No symbol table info available.
#3 0x0000000800d70afd in __gnu_cxx::__verbose_terminate_handler () at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/libsupc++/vterminate.cc:95
terminating = true
t = <optimized out>
#4 0x0000000800d6db48 in __cxxabiv1::__terminate (handler=<optimized out>) at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/libsupc++/eh_terminate.cc:47
No locals.
#5 0x0000000800d6dbb1 in std::terminate () at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/libsupc++/eh_terminate.cc:57
No locals.
#6 0x0000000800d6ddc8 in __cxxabiv1::__cxa_throw (obj=obj@entry=0x80245e0a0, tinfo=0x801068bc0 <typeinfo for std::system_error>, dest=0x800d9f3b0 <std::system_error::~system_error()>)
at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/libsupc++/eh_throw.cc:87
globals = <optimized out>
#7 0x0000000800d9ccd1 in std::__throw_system_error (__i=11) at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/src/c++11/functexcept.cc:130
No locals.
#8 0x0000000800d9f92c in std::thread::join (this=0x802052408) at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/src/c++11/thread.cc:139
__e = <optimized out>
#9 0x00000000004355bf in GraylogConnection::EndThread (this=0x802052378) at /root/MyProject/lib/graylog-logger/src/GraylogConnection.cpp:64
No locals.
#10 0x000000000043546e in GraylogConnection::~GraylogConnection (this=0x802052378, __in_chrg=<optimized out>) at /root/MyProject/lib/graylog-logger/src/GraylogConnection.cpp:47
No locals.
#11 0x0000000000405bcf in GraylogInterface::~GraylogInterface (this=0x802052300, __in_chrg=<optimized out>) at /root/MyProject/lib/graylog-logger/src/GraylogInterface.cpp:18
No locals.
#12 0x0000000000405bfc in GraylogInterface::~GraylogInterface (this=0x802052300, __in_chrg=<optimized out>) at /root/MyProject/lib/graylog-logger/src/GraylogInterface.cpp:20
No locals.
#13 0x00000000004059c6 in std::_Sp_counted_ptr<BaseLogHandler*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x80205c080) at /usr/local/lib/gcc6/include/c++/bits/shared_ptr_base.h:372
No locals.
#14 0x00000000004056bc in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x80205c080) at /usr/local/lib/gcc6/include/c++/bits/shared_ptr_base.h:150
No locals.
#15 0x0000000000405285 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x802018058, __in_chrg=<optimized out>) at /usr/local/lib/gcc6/include/c++/bits/shared_ptr_base.h:662
No locals.
#16 0x00000000004052a4 in std::__shared_ptr<BaseLogHandler, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x802018050, __in_chrg=<optimized out>) at /usr/local/lib/gcc6/include/c++/bits/shared_ptr_base.h:928
No locals.
#17 0x00000000004052c0 in std::shared_ptr<BaseLogHandler>::~shared_ptr (this=0x802018050, __in_chrg=<optimized out>) at /usr/local/lib/gcc6/include/c++/bits/shared_ptr.h:93
No locals.
#18 0x000000000040b8ff in std::_Destroy<std::shared_ptr<BaseLogHandler> > (__pointer=0x802018050) at /usr/local/lib/gcc6/include/c++/bits/stl_construct.h:93
No locals.
#19 0x000000000040b7e9 in std::_Destroy_aux<false>::__destroy<std::shared_ptr<BaseLogHandler>*> (__first=0x802018050, __last=0x802018060) at /usr/local/lib/gcc6/include/c++/bits/stl_construct.h:103
No locals.
#20 0x000000000040b6d4 in std::_Destroy<std::shared_ptr<BaseLogHandler>*> (__first=0x802018050, __last=0x802018060) at /usr/local/lib/gcc6/include/c++/bits/stl_construct.h:126
No locals.
#21 0x000000000040b57f in std::_Destroy<std::shared_ptr<BaseLogHandler>*, std::shared_ptr<BaseLogHandler> > (__first=0x802018050, __last=0x802018060) at /usr/local/lib/gcc6/include/c++/bits/stl_construct.h:151
No locals.
#22 0x000000000040d508 in std::vector<std::shared_ptr<BaseLogHandler>, std::allocator<std::shared_ptr<BaseLogHandler> > >::_M_erase_at_end (this=0x656c00 <Logger::Inst()::inst+32>, __pos=0x802018050)
at /usr/local/lib/gcc6/include/c++/bits/stl_vector.h:1436
No locals.
#23 0x000000000040cfa4 in std::vector<std::shared_ptr<BaseLogHandler>, std::allocator<std::shared_ptr<BaseLogHandler> > >::clear (this=0x656c00 <Logger::Inst()::inst+32>)
at /usr/local/lib/gcc6/include/c++/bits/stl_vector.h:1210
No locals.
#24 0x000000000040c921 in LoggingBase::RemoveAllHandlers (this=0x656be0 <Logger::Inst()::inst>) at /root/MyProject/lib/graylog-logger/src/LoggingBase.cpp:147
guard = {_M_device = @0x656bf0}
#25 0x0000000000406cb8 in Log::RemoveAllHandlers () at /root/MyProject/lib/graylog-logger/src/Log.cpp:52
No locals.
#26 0x0000000000404fef in doQuit () at /root/MyProject/src/main.cpp:11
No locals.
#27 0x0000000000405009 in onSignal (signum=2) at /root/MyProject/src/main.cpp:18
Backtrace when not using Log::RemoveAllHandlers();
:
#0 0x000000080156b35a in thr_kill () from /lib/libc.so.7
No symbol table info available.
#1 0x000000080156b346 in raise () from /lib/libc.so.7
No symbol table info available.
#2 0x000000080156b2c9 in abort () from /lib/libc.so.7
No symbol table info available.
#3 0x0000000800d70afd in __gnu_cxx::__verbose_terminate_handler () at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/libsupc++/vterminate.cc:95
terminating = true
t = <optimized out>
#4 0x0000000800d6db48 in __cxxabiv1::__terminate (handler=<optimized out>) at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/libsupc++/eh_terminate.cc:47
No locals.
#5 0x0000000800d6cb79 in __cxa_call_terminate (ue_header=ue_header@entry=0x80245e080) at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/libsupc++/eh_call.cc:54
No locals.
#6 0x0000000800d6d4cd in __cxxabiv1::__gxx_personality_v0 (version=<optimized out>, actions=<optimized out>, exception_class=5138137972254386944, ue_header=<optimized out>,
context=0x7fffdfdfbdd8) at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/libsupc++/eh_personality.cc:676
found_type = <optimized out>
info = {Start = 140736949370328, LPStart = 4462776, ttype_base = 4472896, TType = 0x7fffdfdfba98 "", action_table = 0x4418c1 "zPLR", ttype_encoding = 112 'p',
call_site_encoding = 60 '<'}
language_specific_data = <optimized out>
action_record = <optimized out>
p = <optimized out>
landing_pad = <optimized out>
ip = <optimized out>
handler_switch_value = <optimized out>
thrown_ptr = 0x0
foreign_exception = <optimized out>
ip_before_insn = 0
#7 0x00000008012a4936 in ?? () from /lib/libgcc_s.so.1
No symbol table info available.
#8 0x00000008012a463c in _Unwind_RaiseException () from /lib/libgcc_s.so.1
No symbol table info available.
#9 0x0000000800d6ddbb in __cxxabiv1::__cxa_throw (obj=obj@entry=0x80245e0a0, tinfo=0x801068bc0 <typeinfo for std::system_error>, dest=0x800d9f3b0 <std::system_error::~system_error()>)
at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/libsupc++/eh_throw.cc:82
globals = <optimized out>
#10 0x0000000800d9ccd1 in std::__throw_system_error (__i=11) at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/src/c++11/functexcept.cc:130
No locals.
#11 0x0000000800d9f92c in std::thread::join (this=0x802052408) at /wrkdirs/usr/ports/lang/gcc6/work/gcc-6.3.0/libstdc++-v3/src/c++11/thread.cc:139
__e = <optimized out>
#12 0x00000000004355bb in GraylogConnection::EndThread (this=0x802052378) at /root/MyProject/lib/graylog-logger/src/GraylogConnection.cpp:64
No locals.
#13 0x000000000043546a in GraylogConnection::~GraylogConnection (this=0x802052378, __in_chrg=<optimized out>) at /root/MyProject/lib/graylog-logger/src/GraylogConnection.cpp:47
No locals.
#14 0x0000000000405bcb in GraylogInterface::~GraylogInterface (this=0x802052300, __in_chrg=<optimized out>) at /root/MyProject/lib/graylog-logger/src/GraylogInterface.cpp:18
No locals.
#15 0x0000000000405bf8 in GraylogInterface::~GraylogInterface (this=0x802052300, __in_chrg=<optimized out>) at /root/MyProject/lib/graylog-logger/src/GraylogInterface.cpp:20
No locals.
#16 0x00000000004059c2 in std::_Sp_counted_ptr<BaseLogHandler*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x80205c080) at /usr/local/lib/gcc6/include/c++/bits/shared_ptr_base.h:372
#include <iostream>
#include <signal.h>
#include <thread>
#include <chrono>
#include <graylog_logger/Log.hpp>
#include <graylog_logger/GraylogInterface.hpp>
void doQuit()
{
// Close GrayLog connection
Log::RemoveAllHandlers();
exit(EXIT_SUCCESS);
}
void onSignal(int signum)
{
doQuit();
}
int main(int argc, char** argv)
{
signal(SIGINT, onSignal);
// Open GrayLog connection
Log::RemoveAllHandlers();
Log::AddLogHandler(new GraylogInterface("http://192.168.1.20", 11111));
Log::SetMinimumSeverity(Severity::Informational);
// In my own code I listen to a network interface and I stop listening if a certain condition is true. For this example lets just use a while(true).
while(true) {
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
Log::Msg(Severity::Informational, "Random log message...");
}
doQuit();
}
from graylog-logger.
So, on my development machine I get no error. Ill try to test it on a FreeBSD machine as well.
from graylog-logger.
I tried it on MacOS too and it didn't throw an error either. But it's hard to imagine that this is something BSD related.
from graylog-logger.
I installed FreeBSD 11 on a virtual machine to test it. Some of the unit tests failed which makes me think that the graylog communication code will not work regardless. This is not very surprising. However, I was still unable to reproduce the error messages you got. I compiled the application using gcc 6.3.
Can you give me the script or command you used to compile the application as well?
As mentioned above, I have intended to re-write the graylog communication code for a while (for several reasons). If there is a real need for this I might be able to find time to do it (or at least get started) next week.
from graylog-logger.
I just tried changing connectionThread.join()
to connectionThread.detach()
. This works since the thread stops itself afterwards (because closeThread
is true), but I think this is a pretty dirty fix.
Here is some stuff from my CMakeLists.txt file.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -std=c++11 -lpthread")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(Boost_USE_STATIC_LIBS ON)
set(GRAYLOG_LOGGER_STANDALONE OFF)
set(BUILD_SHARED_LIBRARIES OFF)
set(PROJECT_ROOT "${CMAKE_CURRENT_BINARY_DIR}/..")
MESSAGE("Building type ${CMAKE_BUILD_TYPE}")
IF(CMAKE_BUILD_TYPE STREQUAL "Release")
MESSAGE("Linking static libgcc & libstdc")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
ENDIF()
And I compile using only the debug flags
cmake .. -DCMAKE_BUILD_TYPE=Debug
make -da
from graylog-logger.
The example I tested which (despite my best efforts) does not crash, can be found in the following gist: https://gist.github.com/SkyToGround/eb17d4a311171763755c000e097d3336
from graylog-logger.
Yeah, using detach()
instead of join()
defeats the purpose of doing a clean shutdown. Without being able to reproduce the error you are getting I will not make that change to the code.
from graylog-logger.
@SkyToGround Could you try this out? By exactly following the steps in How to
I can reproduce the error.
https://gist.github.com/tijme/6c71d03d12f9fb8c3f6e93cf9035ee1a
from graylog-logger.
Now we are getting somewhere. The project does not appear to compile with gcc6 in my setup.
from graylog-logger.
I got errors when compiling console_logger & unit_tests too, but because I didn't need them I introduced the functionality in the CMakeLists.txt to not compile them. But it would be nice if the unit tests worked though.
from graylog-logger.
This is what I have found so far:
- FreeBSD
- Version 12, no problem
- Version 11, will not compile using GCC, no problem with Clang
- Version 10, crashes on exit with both GCC and Clang
- MacOSX
- No problem with Clang
- No problem when using GCC 5 or 6
- Linux
- Centos 7, no problem when using GCC4
- Ubuntu 16, no problem when using GCC6
In my tests, the problem appears to be isolated to older versions of FreeBSD. Seeing as I am running out of ideas, I will leave this issue as it is. At least for the moment.
from graylog-logger.
@SkyToGround Ok, thanks for all the help/research so far!
I am running pfSense (based on FreeBSD 10), so unfortunately I am not able to update to 12.
If I have a solution for the problem, I'll let you know.
from graylog-logger.
I found a relatively serious bug related to deallocation order of static objects. This bug presented itself only in certain circumstances. You might want to check if this bug fix solves your problem.
from graylog-logger.
@SkyToGround I just tried but unfortunately it didn't fix my problem.
from graylog-logger.
Hmm. I tried to print the ID of the main thread and the connection thread like so;
void GraylogConnection::EndThread() {
closeThread = true;
std::cout << "THIS ID: " << std::this_thread::get_id() << std::endl;
std::cout << "THREAD ID: " << connectionThread.get_id() << std::endl;
connectionThread.join();
if (NULL != conAddresses) {
freeaddrinfo(conAddresses);
conAddresses = NULL;
}
}
And this is the output;
THIS ID: 0x801c06c00
THREAD ID: 0x801c06c00
The documentation states that if the ID's are the same, the resource deadlock avoided exception will be thrown (link).
Could this be the problem?
Btw, I don't know if i'm getting the "main thread" ID correctly by calling std::this_thread::get_id()
, because when I run that piece of code directly in the main() function of my application it outputs a different ID.
Edit:
I just tried this on my Mac (where the logger works like it should) and it outputs different ID's.
THIS ID: 0x7fff9acb93c0
THREAD ID: 0x700005e1b000
from graylog-logger.
@SkyToGround Fixed it 😀! It's not an issue in the logger itself. It's how I handled sigints.
I asked the question on StackOverflow and the solution in the answer fixed my problem.
https://stackoverflow.com/questions/44272312/c-different-threads-have-the-same-thread-id-on-freebsd-10
from graylog-logger.
@SkyToGround 已修复😀!这不是记录器本身的问题。这就是我处理信号的方式。
我在 StackOverflow 上问了这个问题,答案中的解决方案解决了我的问题。 https://stackoverflow.com/questions/44272312/c-different-threads-have-the-same-thread-id-on-freebsd-10
hello,can you show how you fix this problem by still using join() method when stop()?it occured to also,thanks~
from graylog-logger.
Related Issues (10)
- tensorflow-terminate called after throwing an instance of 'std::system_error'
- Implement as a spdlog plugin? HOT 2
- Rotate log files HOT 1
- "Informational" sounds awkward HOT 1
- Better error handling for file writing
- Support MSVC
- ASIO need not be exposed in public headers HOT 1
- [feature request] Ability to flush logs HOT 4
- Issues with new Fmt support HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graylog-logger.