apache / apache/logging-log4cxx
[BUG] Segmentation fault (core dump) in Log4cxx 1.7.0 with Intel oneAPI icpx (works in 0.10.0)
- Dominant language
- C++
- Stars
- 301
- Forks
- 142
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 29
Description
A sample program that runs successfully with log4cxx-0.10.0 triggers a core dump when compiled and run with log4cxx-1.7.0. This appears to be a regression or a compatibility issue with the Intel oneAPI compiler.
Please find below sample code(save as sample_log4cxx.cpp file) and the configuration XML file(Log4cxxConfig.xml) is attached for your review.
**Environment Details:**
OS: Oracle Linux Server 8.8
GCC Version: 8.5.0 20210514 (Red Hat 8.5.0-18.0.2)
Compiler: Intel(R) oneAPI DPC++/C++ Compiler 2025.2.1
1) Compile the attached sample_log4cxx.cpp using the following command:
icpx -std=c++17 sample_log4cxx.cpp -I/opt/apache/log4cxx-1.7.0/include -L/opt/apache/log4cxx-1.7.0/lib -llog4cxx -lapr-1 -laprutil-1 -o sample_log4cxx
2) Place Log4cxxConfig.xml in the working directory.
3)Execute the binary:
./sample_log4cxx ./Log4cxxConfig.xml
Please let me know if there are any specific configurations I am missing or if you need additional debug logs (such as a GDB backtrace).
I appreciate your quick support on this matter.
[Log4cxxConfig.xml](https://github.com/user-attachments/files/26872438/Log4cxxConfig.xml)
**Sample Program:**
// sample_log4cxx.cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if !defined(LOG4CXX)
#define LOG4CXX 1
#endif
#include
using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::spi;
static std::string ToUtf8(const LogString& s) {
std::string out;
Transcoder::encode(s, out);
return out;
}
static void Stage(const std::string& msg) {
std::cout << "[sample_log4cxx] " << msg << std::endl;
}
class SampleDBAppender : public log4cxx::AppenderSkeleton {
public:
DECLARE_LOG4CXX_OBJECT(SampleDBAppender)
BEGIN_LOG4CXX_CAST_MAP()
LOG4CXX_CAST_ENTRY(SampleDBAppender)
LOG4CXX_CAST_ENTRY(log4cxx::Appender)
LOG4CXX_CAST_ENTRY(log4cxx::spi::OptionHandler)
LOG4CXX_CAST_ENTRY_CHAIN(log4cxx::AppenderSkeleton)
END_LOG4CXX_CAST_MAP()
SampleDBAppender() : mClosed(false) {}
~SampleDBAppender() override { close(); }
void setOption(const LogString& option, const LogString& value) override {
std::cout << "[SampleDBAppender::setOption] " << ToUtf8(option) << "=" << ToUtf8(value) << std::endl;
if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("DBBRAND"), LOG4CXX_STR("dbbrand"))) {
mDbBrand = value;
} else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("SQL"), LOG4CXX_STR("sql"))) {
mSql = value;
} else if (StringHelper::startsWith(option, LOG4CXX_STR("SQL_"))) {
if (!mDbBrand.empty()) {
LogString expected = LOG4CXX_STR("SQL_");
expected.append(mDbBrand);
if (StringHelper::equalsIgnoreCase(option, expected, StringHelper::toLowerCase(expected))) {
mSql = value; // SQL_POSTGRESQL etc.
}
}
} else {
AppenderSkeleton::setOption(option, value);
}
}
bool requiresLayout() const override { return true; }
void activateOptions(Pool& p) override {
AppenderSkeleton::activateOptions(p);
std::cout << "[SampleDBAppender::activateOptions] DBBRAND=" << ToUtf8(mDbBrand)
<< " SQL_SELECTED=" << ToUtf8(mSql) << std::endl;
}
void close() override { mClosed = true; }
protected:
void append(const LoggingEventPtr& event, Pool& p) override {
if (mClosed) return;
LogString out;
if (!mSql.empty()) {
PatternLayout layout;
layout.setConversionPattern(mSql);
layout.format(out, event, p);
} else if (getLayout()) {
getLayout()->format(out, event, p);
} else {
out = event->getRenderedMessage();
}
std::cout << "[SampleDBAppender::append] " << ToUtf8(out) << std::endl;
}
private:
bool mClosed;
LogString mDbBrand;
LogString mSql;
};
IMPLEMENT_LOG4CXX_OBJECT(SampleDBAppender)
LOG4CXX_PTR_DEF(SampleDBAppender);
class SampleASyncAppender : public log4cxx::AsyncAppender {
public:
DECLARE_LOG4CXX_OBJECT(SampleASyncAppender)
BEGIN_LOG4CXX_CAST_MAP()
LOG4CXX_CAST_ENTRY(SampleASyncAppender)
LOG4CXX_CAST_ENTRY(log4cxx::Appender)
LOG4CXX_CAST_ENTRY(log4cxx::spi::OptionHandler)
LOG4CXX_CAST_ENTRY_CHAIN(log4cxx::AsyncAppender)
END_LOG4CXX_CAST_MAP()
SampleASyncAppender() {}
~SampleASyncAppender() override { close(); }
void setOption(const LogString& option, const LogString& value) override {
std::cout << "[SampleASyncAppender::setOption] " << ToUtf8(option) << "=" << ToUtf8(value) << std::endl;
// Mirror wlserver custom-appender parsing behavior:
// consume known options and ignore unknown ones.
if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("DSN"), LOG4CXX_STR("dsn"))) {
mDsn = value;
} else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("USER"), LOG4CXX_STR("user"))) {
mUser = value;
} else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("PASSWORD"), LOG4CXX_STR("password"))) {
mPassword = value;
} else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("DBBRAND"), LOG4CXX_STR("dbbrand"))) {
mDbBrand = value;
} else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("SQL"), LOG4CXX_STR("sql"))) {
mSql = value;
} else if (StringHelper::startsWith(option, LOG4CXX_STR("SQL_")) ||
StringHelper::startsWith(option, LOG4CXX_STR("INSERTSQL_"))) {
// keep for parity; not executed in this sample
} else {
// intentionally ignored (ex: BLOCKING, BUFFERSIZE)
}
}
void activateOptions(Pool& p) override {
std::cout << "[SampleASyncAppender::activateOptions] enter" << std::endl;
AsyncAppender::activateOptions(p);
std::cout << "[SampleASyncAppender::activateOptions] done" << std::endl;
}
private:
LogString mDsn;
LogString mUser;
LogString mPassword;
LogString mDbBrand;
LogString mSql;
};
IMPLEMENT_LOG4CXX_OBJECT(SampleASyncAppender)
LOG4CXX_PTR_DEF(SampleASyncAppender);
int main(int argc, char** argv) {
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " /path/to/Log4cxxConfig.xml\n";
return 1;
}
const std::string configPath = argv[1];
Stage("Program started");
Stage("Input config: " + configPath);
Stage("Registering classes");
SampleDBAppender::registerClass();
SampleASyncAppender::registerClass();
Stage("Enabling internal log4cxx debug");
log4cxx::helpers::LogLog::setInternalDebugging(true);
Stage("Calling DOMConfigurator::configure()");
try {
log4cxx::xml::DOMConfigurator::configure(configPath.c_str());
} catch (const std::system_error& ex) {
std::cerr << "[sample_log4cxx] std::system_error from configure: " << ex.what() << std::endl;
return 10;
} catch (const std::exception& ex) {
std::cerr << "[sample_log4cxx] std::exception from configure: " << ex.what() << std::endl;
return 11;
} catch (...) {
std::cerr << "[sample_log4cxx] Unknown exception from configure" << std::endl;
return 12;
}
Stage("DOMConfigurator::configure() returned");
LoggerPtr root = Logger::getRootLogger();
Stage("Emitting test logs");
LOG4CXX_INFO(root, "sample info");
LOG4CXX_WARN(root, "sample warn");
LOG4CXX_ERROR(root, "sample error");
Stage("Shutting down LogManager");
LogManager::shutdown();
Stage("Completed successfully");
return 0;
}
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by compiling and running sample_log4cxx.cpp with Intel oneAPI icpx and Log4cxxConfig.xml using the command in the issue, then compare the behavior with log4cxx-0.10.0. Trace the crash with GDB if it reproduces, and use the backtrace to determine whether the regression is in configuration, custom appenders, asynchronous logging, or compiler compatibility.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100