I tried to encapsulate using log4cxx in our code by using #define directives and macros. The code compiles but when running I get Access violation, because I believe the stream object is not correctly initialized.
The header file which tries to make log4cxx pluggable looks like this:
#ifdef USE_LOG4CXX
#include "log4cxx/logger.h"
#define LOG_DEBUG(msg) LOG4CXX_DEBUG(logger, msg)
#define LOG_INFO(msg) LOG4CXX_INFO(logger, msg)
#define LOG_WARN(msg) LOG4CXX_WARN(logger, msg)
#define LOG_ERROR(msg) LOG4CXX_ERROR(logger, msg)
#define LOGGER_DECL static const log4cxx::LoggerPtr logger
#define LOGGER_INIT(source,name) const log4cxx::LoggerPtr source::logger = log4cxx::Logger::getLogger(#name);
#else // use some other log method, e.g. stdout which worked fine
The .cpp file does the logging like this:
LOG_INFO("state(): " << old_state << " ==> " << new_state );
The preprocessor expanded the .cpp file to:
{ if (logger->isInfoEnabled()) { ::log4cxx::helpers::MessageBuffer oss_; logger->forcedLog(::log4cxx::Level::getInfo(), oss_.str(oss_ << "state(): " << state_ << " ==> " << new_state), ::log4cxx::spi::LocationInfo("c:\\dev\\ezx-capi\\iserver-api\\iserver_client.cpp", __FUNCSIG__ , 190)); }};
The data type of old_state and new_state are int.
When running, the application fails on:
std::basic_ostream<char>& operator<<(CharMessageBuffer& os, const V& val) {
return ((std::basic_ostream<char>&) os) << val;
}
In the debugger, the problem looks like the CharMessageBuffer object has a std::basic_streambuf member which is not initialized, and so when it goes to append the value, it dies. (I'm not sure about that explanation though.)
Drilling all the way down, it dies in std::basic_ostream:
_Myt& __CLR_OR_THIS_CALL operator<<(int _Val)
{ // insert an int
ios_base::iostate _State = ios_base::goodbit;
const sentry _Ok(*this); // dies right here, in the constructor
Anyway, I realize this has something to do with how I am using a macro to invoke LOG4CXX. (When I had the USE_LOG4FXX not defined, all the log statements were going to std::cout and it worked fine.)
UPDATE
One other piece of information - it seems that this is only failing when I invoke the logging from within a static library. If I use the same (or similar) macro from an EXE project, it doesn't fail at all. So I can't seem to replicate this problem in some kind of separate test application.
The problem was caused by the way the enum was interpreted. The compiler invoked the template << operator, instead of the version of the << operator which took an int type. What was even stranger (to me), was that a test app I wrote to see whether the enum data type was the problem worked without issue, i.e.:
ezx::net::client_state::state mystate = ezx::net::client_state::connecting;
LOG_INFO("this should show new state" << mystate);
This did not throw any error, and took a different code path than the same code above.
The conclusion I reached was that the log4cxx implementation of this operator is fragile, in that it will compile fine, but then fail unexpectedly at runtime, depending on whether the datatype is dispatched to the correct version of the operator or not.
Related
I use #warning to mark some unfinished functions, so that when someone compiles the code later, they see a hint that they still need to continue to implement. for example:
class HttpDownloadJobAndroid : public HttpDownloadJob
{
public:
virtual void Download() override
{
#warning "Please complete the implementation of the function : HttpDownloadJobAndroid::Download"
Finished = true;
Success = false;
}
};
This works great, but there is a small problem that every time I copy and paste this warning into a new function, I always need to change the function name in it. This will undoubtedly affect some work efficiency. So I thought, is it possible to pack a C++ macro like __FUNCTION__ into this string so I can copy this warning anywhere.
#define _ME_PP_TEXT(Expr) #Expr
#define ME_PP_TEXT(Expr) _ME_PP_TEXT(Expr)
// not work
#warning "Please complete the implementation of the function : " __FUNCTION__
// not work too...
#warning "Please complete the implementation of the function : " ME_PP_TEXT(__FUNCTION__)
I've tried this method, but it doesn't seem to work.
Of course, if there are other better solutions, please teach me, thank you.
my compiler is Clang 5.0, target platform is android.
Is it possible to ensure that the message macro parameter of BOOST_TEST is only evaluated, if the check actually fails. Lazy evaluation seems to happen for human readable output format, but not for JUnit output format. Can I somehow make lazy evaluation work reliably for all output types?
MCVE
#define BOOST_TEST_MODULE my_module
#include <boost/test/included/unit_test.hpp>
#include <string>
struct S
{
std::string m_value;
};
S* f(void)
{
return nullptr;
}
BOOST_AUTO_TEST_CASE(foo_test)
{
S* result = f();
BOOST_TEST(result == nullptr, "f() should return nullptr but returned a object with m_value = " << result->m_value);
}
This code works fine if I use human readable output format (--log_format=HRF command line option for executable). Using JUnit output (--log_format=JUNIT command line option) results in a access error, since the program attempts to get the size of a string at address 0.
This is a bit unexpected, since I'd assume the BOOST_TEST macro would work similar to this
// not the real macro, but one that works in a way I'd expect it to work
#define BOOST_TEST(condition, message) if (!(condition)) { \
some_output_stream << "The following test failed: " << #condition << std::endl \
<< "Message: " << message; \
}
Tested configurations:
boost 1.75.0
Visual Studio 2017/2019 or g++ 8.x (Win 10 / Ubuntu 18)
64 bit
I am trying to unit test an HTTP API written in C++:
void getLogNames(Request & req, Response & res)
{
vector<string> files = getFilesInDirectory(LOG_LOCATION, ".log", false);
json response(files);
res.send(response);
}
The problem is that LOG_LOCATION is included from common.h and is const, and can't be changed by my testing code:
const std::string LOG_LOCATION = "/var/log"
I've tried doing this at the top of the file:
#ifdef UNIT_TEST
#include <common_mock.h>
#else
#include <common.h>
#endif
However, common.h is included in some shared libraries that are being linked in, and I would have to add UNIT_TEST hooks to all those files and rebuild the shared libraries as well, which I would rather avoid...
Is there an easier way I could be doing this, some #define tricks or something?
Well, you can try to const_cast a pointer to your LOG_LOCATION but it's dirty and unreliable solution and may cause seg fault. For example:
original_file.h
#include <iostream>
const std::string LOG_LOCATION = "/var/log";
int func() {
std::cout << LOG_LOCATION << std::endl;
}
unit_test.cpp
#include "test.h"
void someUnitTest() {
const std::string* cs = &LOG_LOCATION;
std::string* s = const_cast<std::string*>(cs);
*s = "NEW_VALUE";
std::cout << *s;
}
int main() {
someUnitTest();
}
This code may work in some cases (i.e. this successfully compiled and worked in GCC but only for class object type - it crashes with buildin type like int) but is may change with different compilers, platforms, or optimization levels.
The recommended way is to redesign your application and use dependency injections, for example wrap your function calls in a class and put this location as a settable member.
Why don’t you change your class to receive the log location in its constructor? By hardcoding it (macros are eqivalent to hardcoding from the testing point of view) you’re purposely making your class less testable.
This is my first question on this website, I hope I'll do it just fine.
I'm doing a Qt Project at work using a lot of signals and slots and I would like to create a flag/macro/variable to activate/deactivate the use of std::cout to trace which signal is emitted and which slot is activated.
This is for debugging purpose, to know how the different components of the application exchange and avoid loops in signals/slots.
More specifically, I would have a flag/variable in my .pro :
QT_SIGNALS_SLOTS_LOG = true
and in my source code :
if(QT_SIGNALS_SLOTS_LOG)
std::cout << "MyClass::slotMySlot activated" << std::endl;
Questions :
1. Can I do something like that (using a variable of the .pro in the
code) ?
2. Is there a better way of doing that ?
UPDATE 1
Burich, this works just fine, thanks
Now I will try to code a Qt macro which I put in my slots and wich does all the work
Example :
Q_SIGNALS_SLOTS_LOG();
which gets the names of the Class and the Slot and do the
ifdef QT_SIGNALS_SLOTS_LOG
std::cout << "MyClass::slotMySlot activated" << std::endl;
endif
Is there a way of doing that ?
UPDATE 2
I used QLoggingCategory Class with this tutorial
I have a Class in my Utils folder with this code
#ifndef SIGNALSLOTDEBUG_H
#define SIGNALSLOTDEBUG_H
#include<QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(logSignal)
Q_DECLARE_LOGGING_CATEGORY(logSlot)
inline static void debugSlotF( char const * caller_name )
{
qCDebug(logSlot) << __TIME__ << caller_name << "activated";
}
inline static void debugSlot(){
}
#define debugSlot() debugSlotF(__PRETTY_FUNCTION__)
#endif // SIGNALSLOTDEBUG_H
In my code I just call
void HorizontalPatternListScene::slotSelectionChanged(int i)
{
debugSlot();
....
I get this output :
log.slot: 12:06:54 void HorizontalPatternListScene::slotSelectionChanged(int) activated
And I can disable the stream by doing
QLoggingCategory::setFilterRules(
"log.slot=true\n"
"log.signal=false");
in my main.cpp
Set variable in pro:
DEFINES += QT_SIGNALS_SLOTS_LOG
Test it in code:
#ifdef QT_SIGNALS_SLOTS_LOG
std::cout << "MyClass::slotMySlot activated" << std::endl;
#endif
If you're willing to use C++11 features for this, you can so the following:
#ifdef DEBUGMYCODE
template<typename... ArgTypes>
inline void print(ArgTypes... args)
{
// trick to expand variadic argument pack without recursion
using expand_variadic_pack = int[];
// first zero is to prevent empty braced-init-list
// void() is to prevent overloaded operator, messing things up
// trick is to use the side effect of list-initializer to call a function on every argument, in order.
// (void) is to suppress "statement has no effect" warnings
#ifdef _WIN32
std::stringstream stream;
(void)expand_variadic_pack{0, ((stream << args), void(), 0)... };
std::wstring stuff = convert_to_utf16(stream.str());
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), stuff.c_str(), stuff.size(), nullptr, nullptr);
#else
(void)expand_variadic_pack{0, ((std::cout << args), void(), 0)... };
#endif
}
#else
#define debug_print(...)
#endif
I use this in my code as a general "print" function and add a debug enum on top to handle debug types being output at runtime.
It handles UTF-8 strings on Windows as a bonus, and handles anything that can be dumped to std::cout. You can also change what stream it outputs to, or really whatever the body of the function does.
If the macro DEBUGMYCODE is not defined, all calls to debug_print are fully removed by the preprocessor.
PS: if it's Qt you're coding, you should really use qDebug() which handles this for you in an entirely different manner.
I want to implement a function tracer, which would trace how much time a function is taking to execute. I have following class for the same:-
class FuncTracer
{
public:
FuncTracer(LPCTSTR strFuncName_in)
{
m_strFuncName[0] = _T('\0');
if( strFuncName_in ||
_T('\0') != strFuncName_in[0])
{
_tcscpy(m_strFuncName,strFuncName_in);
TCHAR strLog[MAX_PATH];
_stprintf(strLog,_T("Entering Func:- <%s>"),m_strFuncName);
LOG(strLog)
m_dwEnterTime = GetTickCount();
}
}
~FuncTracer()
{
TCHAR strLog[MAX_PATH];
_stprintf(strLog,_T("Leaving Func:- <%s>, Time inside the func <%d> ms"),m_strFuncName, GetTickCount()-m_dwEnterTime);
LOG(strLog)
}
private:
TCHAR m_strFuncName[MAX_PATH];
DWORD m_dwEnterTime;
};
void TestClass::TestFunction()
{
// I want to avoid writing the function name maually..
// Is there any macro (__LINE__)or some other way to
// get the function name inside a function ??
FuncTracer(_T("TestClass::TestFunction"));
/*
* Rest of the function code.
*/
}
I want to know if there is any way to get the name of the function from inside of a function? Basically I want the users of my class to simply create an object the same. They may not pass the function name.
C99 has __func__, but for C++ this will be compiler specific. On the plus side, some of the compiler-specific versions provide additional type information, which is particularly nice when you're tracing inside a templatized function/class.
MSVC: __FUNCTION__, __FUNCDNAME__, __FUNCSIG__
GCC: __func__, __FUNCTION__, __PRETTY_FUNCTION__
Boost library has defined macro BOOST_CURRENT_FUNCTION for most C++ compilers in header boost/current_function.hpp. If the compiler is too old to support this, the result will be "(unknown)".
VC++ has
__FUNCTION__ for undecorated names
and
__FUNCDNAME__ for decorated names
And you can write a macro that will itself allocate an object and pass the name-yelding macro inside the constructor. Smth like
#define ALLOC_LOGGER FuncTracer ____tracer( __FUNCTION__ );
C++20 std::source_location::function_name
main.cpp
#include <iostream>
#include <string_view>
#include <source_location>
void log(std::string_view message,
const std::source_location& location = std::source_location::current()
) {
std::cout << "info:"
<< location.file_name() << ":"
<< location.line() << ":"
<< location.function_name() << " "
<< message << '\n';
}
int f(int i) {
log("Hello world!"); // Line 16
return i + 1;
}
int f(double i) {
log("Hello world!"); // Line 21
return i + 1.0;
}
int main() {
f(1);
f(1.0);
}
Compile and run:
g++ -ggdb3 -O0 -std=c++20 -Wall -Wextra -pedantic -o source_location.out source_location.cpp
./source_location.out
Output:
info:source_location.cpp:16:int f(int) Hello world!
info:source_location.cpp:21:int f(double) Hello world!
so note how the call preserves caller information, so we see the desired main call location instead of log.
I have covered the relevant standards in a bit more detail at: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?
Tested on Ubuntu 22.04, GCC 11.3.
I was going to say I didn't know of any such thing but then I saw the other answers...
It might interest you to know that an execution profiler (like gprof) does exactly what you're asking about - it tracks the amount of time spent executing each function. A profiler basically works by recording the instruction pointer (IP), the address of the currently executing instruction, every 10ms or so. After the program is done running, you invoke a postprocessor that examines the list of IPs and the program, and converts those addresses into function names. So I'd suggest just using the instruction pointer, rather than the function name, both because it's easier to code and because it's more efficient to work with a single number than with a string.