Comments (13)
Also realized that if I build log4cplus as static library(BUILD_SHARED_LIBS is false), now it doesnt crash but hangs at native exit function.
#if !defined (_KERNELX)
_tinitenv = _tenviron;
mainret = _tmain(__argc, _targv, _tenviron);
#else /* !defined (_KERNELX) */
mainret = _tmain(0, NULL, NULL);
#endif /* !defined (_KERNELX) */
#endif /* _WINMAIN_ */
if ( !managedapp )
exit(mainret); <-------------- HANGS HERE
_cexit();
With debugging I saw that now Hierarchy::shutdown()
is not being called
from log4cplus.
Is this the master branch version? If it is, use log4cplus::Initializer initializer;
instead of calling log4cplus::initialize();
from log4cplus.
Oh wow, I should have checked the tests , I simply followed the wiki on the sourceforge. Thanks for the quick response, it works now!
from log4cplus.
I'm reopening this since I can't quite figure out why things dont work with log4cplus.
- Msvc Vs2013 x64 Debug
- master branch of log4cplus
- log4cplus as static library compiled with /MDd
I'm initializing log4cplus from a shared library compiled with /MDd. I have reduced the code to minimalize it to be able to post here so here is my code
First the main function in the executable,
namespace YumeEngine
{
#if defined(_MSC_VER)
#define YUME_MAIN(function) \
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR cmdLine, int showCmd) \
{ \
YumeEngine::ParseArguments(GetCommandLineA()); \
return function; \
}
#else
#define YUME_MAIN(function) \
int main(int argc, char** argv) \
{ \
YumeEngine::ParseArguments(argc, argv); \
return function; \
}
#endif
}
#define YUME_DEFINE_ENTRY_POINT(className) \
int RunApplication() \
{ \
boost::shared_ptr<className> application(new className); \
return application->Run(); \
} \
YUME_MAIN(RunApplication());
....
YUME_DEFINE_ENTRY_POINT(YumeEngine::HelloWorld);
HelloWorld inherits from the application class and creates a engine pointer
YumeApplication::YumeApplication()
: exitCode_(0)
{
engine_ = boost::shared_ptr<YumeEngine3D>(new YumeEngine3D);
}
The run function
int YumeApplication::Run()
{
Setup();
if(!engine_->Initialize(engineVariants_))
{
exitCode_ = -1;
return exitCode_;
}
Start();
if(exitCode_ == 1)
return exitCode_;
#ifndef YUME_TEST_MODE
while(!engine_->IsExiting())
engine_->Run();
#else
if(!engine_->IsExiting())
engine_->Run();
#endif
engine_->Exit();
return exitCode_;
}
Now the initialize function which has the log4cplus stuff
bool YumeEngine3D::Initialize(const VariantMap& variants)
{
//Initialize other stuff
log4cplus::initialize()
YumeEngine::Log::InitLogging(env_->GetLogFile().generic_string().c_str());
}
InitLogging function
void YumeEngine::Log::InitLogging(const char* loc)
{
loggingEnabled = true;
#if YUME_PLATFORM == YUME_PLATFORM_WIN32
log4cplus::SharedAppenderPtr debugAppender(new log4cplus::Win32ConsoleAppender());
debugAppender->setName(LOG4CPLUS_TEXT("First"));
debugAppender->setLayout(std::unique_ptr<log4cplus::Layout>(new log4cplus::SimpleLayout()));
log4cplus::Logger::getRoot().addAppender(debugAppender);
#else
log4cplus::SharedAppenderPtr debugAppender(new log4cplus::ConsoleAppender());
debugAppender->setName(LOG4CPLUS_TEXT("ConsoleAppender"));
debugAppender->setLayout(std::unique_ptr<log4cplus::Layout>(new log4cplus::TTCCLayout()));
log4cplus::Logger::getRoot().addAppender(debugAppender);
#endif
std::string strModulePath = std::string(loc);
const size_t cSize = strlen(loc);
std::wstring wstrModulePath(cSize, L'#');
mbstowcs(&wstrModulePath[0], loc, cSize);
#if YUME_PLATFORM == YUME_PLATFORM_WIN32
log4cplus::SharedAppenderPtr fileAppender(new log4cplus::RollingFileAppender(wstrModulePath));
#else
log4cplus::SharedAppenderPtr fileAppender(new log4cplus::RollingFileAppender(strModulePath));
#endif
fileAppender->setName(LOG4CPLUS_TEXT("Second"));
fileAppender->setLayout(
std::unique_ptr<log4cplus::Layout>(
new log4cplus::PatternLayout(LOG4CPLUS_TEXT("[%-5p][%D{%Y/%m/%d %H:%M:%S:%q}][%t] %m%n"))));
log4cplus::Logger::getRoot().addAppender(fileAppender);
}
void YumeEngine::Log::StopLogging()
{
log4cplus::Logger::shutdown();
ToggleLogging(false);
}
Exit function
void YumeEngine3D::Exit()
{
//other stuff
YumeEngine::Log::StopLogging();
}
No log4cplus functions are called after the Exit().
With this setup, Win32 console and file appender works just fine, but it crashes while trying to lock a mutex on exit.
> msvcp120d.dll!mtx_do_lock(_Mtx_internal_imp_t * * mtx, const xtime * target) Line 49 C++
msvcp120d.dll!_Mtx_lock(_Mtx_internal_imp_t * * mtx) Line 154 C++
YumeEngine.dll!std::_Mtx_lockX(_Mtx_internal_imp_t * * _Mtx) Line 68 C++
YumeEngine.dll!std::_Mutex_base::lock() Line 42 C++
YumeEngine.dll!std::unique_lock<std::mutex>::unique_lock<std::mutex>(std::mutex & _Mtx) Line 220 C++
YumeEngine.dll!progschj::ThreadPool::wait_until_empty() Line 192 C++
YumeEngine.dll!log4cplus::waitUntilEmptyThreadPoolQueue() Line 298 C++
YumeEngine.dll!log4cplus::Hierarchy::shutdown() Line 244 C++
YumeEngine.dll!log4cplus::Hierarchy::~Hierarchy() Line 81 C++
YumeEngine.dll!log4cplus::`anonymous namespace'::DefaultContext::~DefaultContext() C++
YumeEngine.dll!log4cplus::`anonymous namespace'::DefaultContext::`scalar deleting destructor'(unsigned int) C++
YumeEngine.dll!log4cplus::`anonymous namespace'::destroy_default_context::~destroy_default_context() Line 166 C++
YumeEngine.dll!log4cplus::`anonymous namespace'::`dynamic atexit destructor for 'destroy_default_context_''() C++
YumeEngine.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 416 C
YumeEngine.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 522 C
YumeEngine.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) Line 473 C
ntdll.dll!LdrpCallInitRoutine() Unknown
ntdll.dll!LdrShutdownProcess() Unknown
ntdll.dll!RtlExitUserProcess() Unknown
kernel32.dll!ExitProcessImplementation�() Unknown
msvcr120d.dll!__crtExitProcess(int status) Line 776 C
msvcr120d.dll!doexit(int code, int quick, int retcaller) Line 679 C
msvcr120d.dll!exit(int code) Line 426 C
HelloWorld.exe!__tmainCRTStartup() Line 662 C
HelloWorld.exe!WinMainCRTStartup() Line 466 C
kernel32.dll!BaseThreadInitThunk�() Unknown
ntdll.dll!RtlUserThreadStart() Unknown
Now weirdly enough if I put log4cplus::Initializer initializer;
in the Initialize() _without_ removing log4cplus::initialize()
it doesnt crash. It must be a false positive since when my Initialize() function exits the destructor of log4cplus::Initializer
is called..
So it doesnt crash like this
bool YumeEngine3D::Initialize(const VariantMap& variants)
{
//Initialize other stuff
log4cplus::Initializer initializer;
log4cplus::initialize()
YumeEngine::Log::InitLogging(env_->GetLogFile().generic_string().c_str());
}
Doesnt crash like this too,
bool YumeEngine3D::Initialize(const VariantMap& variants)
{
//Initialize other stuff
log4cplus::Initializer initializer;
YumeEngine::Log::InitLogging(env_->GetLogFile().generic_string().c_str());
}
This is obviously wrong but may give someone a hint.
from log4cplus.
I suggest that you just put log4cplus::Initializer initializer;
at the top of your main()
or WinMain()
, if you are using log4cplus for the whole application. If you want to just use it for your YumEngine3D
class, then I suggest you add it as a member.
I guess I should note that once log4cplus shuts down, I do not think it is possible to re-start it by using the initializer again.
from log4cplus.
I already tried putting it in the top of the main but the outcome did not change.Weird. And I want to be able to turn off logging with a command line argument so putting it as a member or on top of main doesnt seem good for that reason. Maybe put log4cplus::Initializer initializer;
in the class as a pointer?
from log4cplus.
Putting log4cplus::Initializer* initializer_;
as a member pointer works,but it kind of defeats the purpose of the log4cplus::Initializer
class?
Now I can write like this and there is no problem
In the YumeEngine3D::Initialize()
if(env_->GetVariant("enableLogging").Get<bool>())
{
log4cplusinitializer_ = new log4cplus::Initializer;
YumeEngine::Log::InitLogging(env_->GetLogFile().generic_string().c_str());
}
And when exiting,
StopLogging()
delete log4cplusinitializer_;
from log4cplus.
Putting
log4cplus::Initializer* initializer_;
as a member pointer works,but it kind of defeats the purpose of thelog4cplus::Initializer
class?
Yes, that defeats the purpose.
Handle the disabling of the logging by log levels and thresholds or filter settings.
from log4cplus.
I suggest that you just put log4cplus::Initializer initializer;
at the top of your main()
or WinMain()
, if you are using log4cplus for the whole application. If you want to just use it for your YumEngine3D
class, then I suggest you add it as a member.
I guess I should note that once log4cplus shuts down, I do not think it is possible to re-start it by using the initializer again.
from log4cplus.
hi, I have the same problem, crash at threadpool::~threadpool when close loggingserver, Hierarchy not yet execute, stack trace :
ntdll.dll!_TpAllocWait@16�()
kernel32.dll!_CreateThreadpoolWait@12�()
> msvcr120d.dll!__crtCreateThreadpoolWait(void (_TP_CALLBACK_INSTANCE *, void *, _TP_WAIT *, unsigned long) * pfnwa, void * pv, _TP_CALLBACK_ENVIRON_V1 * pcbe) 行 582 C
msvcr120d.dll!Concurrency::details::RegisterAsyncWaitAndLoadLibrary(void * waitingEvent, void (_TP_CALLBACK_INSTANCE *, void *, _TP_WAIT *, unsigned long) * callback, void * data) 行 673 C++
msvcr120d.dll!Concurrency::details::ExternalContextBase::PrepareForUse(bool explicitAttach) 行 120 C++
msvcr120d.dll!Concurrency::details::ExternalContextBase::ExternalContextBase(Concurrency::details::SchedulerBase * pScheduler, bool explicitAttach) 行 48 C++
msvcr120d.dll!Concurrency::details::SchedulerBase::GetExternalContext(bool explicitAttach) 行 1634 C++
msvcr120d.dll!Concurrency::details::SchedulerBase::AttachExternalContext(bool explicitAttach) 行 1582 C++
msvcr120d.dll!Concurrency::details::SchedulerBase::CreateContextFromDefaultScheduler() 行 573 C++
msvcr120d.dll!Concurrency::details::SchedulerBase::CurrentContext() 行 402 C++
msvcr120d.dll!Concurrency::details::LockQueueNode::LockQueueNode(unsigned int timeout) 行 619 C++
msvcr120d.dll!Concurrency::critical_section::lock() 行 1026 C++
msvcp120d.dll!mtx_do_lock(_Mtx_internal_imp_t * * mtx, const xtime * target) 行 67 C++
msvcp120d.dll!_Mtx_lock(_Mtx_internal_imp_t * * mtx) 行 153 C++
log4cplus.dll!std::_Mtx_lockX(_Mtx_internal_imp_t * * _Mtx) 行 68 C++
log4cplus.dll!std::_Mutex_base::lock() 行 41 C++
log4cplus.dll!std::unique_lock<std::mutex>::unique_lock<std::mutex>(std::mutex & _Mtx) 行 220 C++
log4cplus.dll!progschj::ThreadPool::~ThreadPool() 行 179 C++
from log4cplus.
If it is expected (at least under Visual Studio) that the library will be shut down before destroy_default_context::~destroy_default_context()
is called, then it would be logical to log a short message to give a hint what is going wrong.
Here is what I did locally:
diff --git a/src/global-init.cxx b/src/global-init.cxx
index 9a8db64a..50937dc5 100644
--- a/src/global-init.cxx
+++ b/src/global-init.cxx
@@ -163,6 +163,16 @@ struct destroy_default_context
{
~destroy_default_context ()
{
+#if ! defined (LOG4CPLUS_SINGLE_THREADED) && defined (_MSC_VER)
+ if (default_context->thread_pool != nullptr)
+ {
+ helpers::getLogLog().error(
+ LOG4CPLUS_TEXT("Thread pool must be shut down by now. Missed an instance of "\
+ "`log4cplus::Initializer` at the top of main function?"));
+ return;
+ }
+#endif
+
delete default_context;
default_context = nullptr;
default_context_state = DC_DESTROYED;
--
from log4cplus.
I have just merged recent changes to 2.0.x branch. Please try it if it fixes your log4cplus issues.
from log4cplus.
Revision f69f588 seems to fix the problem.
Thanks!
from log4cplus.
Related Issues (20)
- ./configure fails using c++2a HOT 3
- How to configure PatternLayout to use __FUNCTION__ HOT 7
- A link error occurred while compiling the my program. HOT 4
- Question: Effect of LOG4CPLUS_REQUIRE_EXPLICIT_INITIALIZATION on Windows? HOT 5
- Setting log level through env in log config file HOT 3
- Help needed: how to periodically flush logger with appender's immediateFlush set to false? HOT 2
- log file name not change after rollover TimeBasedRollingFileAppender HOT 3
- log's maxsize>200kb,but it dosen't work HOT 2
- Opentelemetry integration HOT 1
- What kind of compilation options can correctly generate a multi-threaded logging library HOT 5
- Win64 application crash on exit HOT 1
- Why mingw can't complie log4cplus-2.1.1? HOT 1
- Sending logs from log4cplus to log4j via TCP HOT 1
- Is it possible to build log4cplus for QNX aarch64le? HOT 3
- Save all configuration in a file HOT 2
- Question: Which latest version of Log4cplus I should use on RedHat 7.9 with DevToolset11-toolchain ( GCC 11.2 ) compiler HOT 7
- Does not work when maxBackupIndex is set to 0 HOT 1
- Include Headers Possibly Causing Build Error HOT 5
- how to set FD_CLOEXEC for log4cplus HOT 1
- Inconsistent Log File Permissions HOT 2
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 log4cplus.