How to view Macro definition value in executable - c++

Been years since I've coded in C/C++ so sorry about the newbie'ish question. I have codebase that compiles differently based upon configurations that are defined via #defines, which can be provided as args to the makefile. Is there a way to encode these #defines so I can look at an executable and see what the define was - e.g.
int main() {
#ifdef CONFIG_A
init_config_a();
#endif
#ifdef CONFIG_B
init_config_b();
#endif
}
#ifdef CONFIG_A
void init_config_a() {
// do something
}
#endif
#ifdef CONFIG_B
void init_config_b() {
// do something for B
}
#endif
How can I tell if a given executable was created with config A or config B. One hack is to look for symbols that are only compiled based upon the definitions (e.g. init_config_a) but that's pretty ugly.
EDIT: Sorry I neglected an important piece of info: the program is actually compiled to run on an embedded system so I can't easily just add a switch or some other mechanism to run the program locally.

Well, your question is not really precise on how you really want to get the information once you have the binary. As solution that does not involved disassembly would be having a struct with that information and initialize it when you want to print that information. Perhaps something as trivial as this:
#include <stdio.h>
#include <string.h>
struct buildinfo {
int CONFIG_A;
int CONFIG_B;
};
void get_build_info(struct buildinfo *info)
{
if(info == NULL)
return;
memset(info, 0, sizeof *info);
#ifdef CONFIG_A
info->CONFIG_A = 1;
#endif
#ifdef CONFIG_B
info->CONFIG_B = 1;
#endif
}
int main(int argc, char **argv)
{
if(argc == 2 && strcmp(argv[1], "-v") == 0)
{
struct buildinfo info;
get_build_info(&info);
printf("build info: CONFIG_A: %s, CONFIG_B: %s\n",
info->CONFIG_A ? "yes" : "no",
info->CONFIG_B ? "yes" ; "no");
return 0;
}
...
return 0;
}
I you don't want to analyse the binary, then you can execute ./yourprogram -v and see the information printed on screen.

The best way will be to name the binary based upon the define used.
If you want to tell whether the binary was build with CONFIG_A or CONFIG_B just by inspection. On possible approach could be the following.
Put a signature depending on the configuration at a specific address (will work at any address too). e.g.
int main() {
#ifdef CONFIG_A
// this sign can be put at specific address with #pragma
const char sign[]="CONFIG_A";
init_config_a();
#elif defined(CONFIG_B) // only one shall be defined at a time
// this sign can be put at specific address with #pragma
const char sign[]="CONFIG_B";
init_config_b();
#endif
}
When you open the binary in a text editor you will be able to see the sign in ASCII view.

Related

Debug Assertion Failed Expression __acrt_first_block == header

I have been trying to figure out why this is happening and maybe it is just due to inexperience at this point but could really use some help.
When I run my code, which is compiled into a DLL using C++20, I get that a debug assertion has failed with the expression being __acrt_first_block == header.
I narrowed down where the code is failing, but the weird part is that it runs just fine when I change the Init(std::string filePath function signature to not contain the parameter. The code is below and hope someone can help.
Logger.h
#pragma once
#include "../Core.h"
#include <memory>
#include <string>
#include "spdlog/spdlog.h"
namespace Ruby
{
class RUBY_API Logger
{
public:
static void Init(std::string filePath);
inline static std::shared_ptr<spdlog::logger>& GetCoreLogger() { return coreLogger; }
inline static std::shared_ptr<spdlog::logger>& GetClientLogger() { return clientLogger; }
private:
static std::shared_ptr<spdlog::logger> coreLogger;
static std::shared_ptr<spdlog::logger> clientLogger;
};
}
Logger.cpp
namespace Ruby
{
std::shared_ptr<spdlog::logger> Logger::coreLogger;
std::shared_ptr<spdlog::logger> Logger::clientLogger;
void Logger::Init(std::string filePath)
{
std::string pattern{ "%^[%r][%n][%l]: %v%$" };
auto fileSink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filePath, true);
// Setup the console and file sinks
std::vector<spdlog::sink_ptr> coreSinks;
coreSinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
coreSinks.push_back(fileSink);
// Bind the sinks to the core logger.
coreLogger = std::make_shared<spdlog::logger>("RUBY", begin(coreSinks), end(coreSinks));
// Set the Patterns for the sinks
coreLogger->sinks()[0]->set_pattern(pattern);
coreLogger->sinks()[1]->set_pattern(pattern);
// Tell spdlog to flush the file loggers on trace or worse message (can be changed if necessary).
coreLogger->flush_on(spdlog::level::trace);
// Set the default level of the logger
coreLogger->set_level(spdlog::level::trace);
// Do the same for the client logger
std::vector<spdlog::sink_ptr> clientSinks;
clientSinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
clientSinks.push_back(fileSink);
clientLogger = std::make_shared<spdlog::logger>("APP", begin(clientSinks), end(clientSinks));
clientLogger->sinks()[0]->set_pattern(pattern);
clientLogger->sinks()[1]->set_pattern(pattern);
clientLogger->flush_on(spdlog::level::trace);
clientLogger->set_level(spdlog::level::trace);
}
}
Entrypoint.h
#pragma once
#ifdef RB_PLATFORM_WINDOWS
extern Ruby::Application* Ruby::CreateApplication();
int main(int argc, char** argv)
{
Ruby::Logger::Init("../Logs/Recent_Run.txt");
RB_CORE_INFO("Initialized the logger.");
auto app = Ruby::CreateApplication();
app->Run();
delete app;
return 0;
}
#else
#error Ruby only supports windows
#endif // RB_PLATFORM_WINDOWS
For anyone else who runs into a similar problem, here is how I fixed it.
Essentially the function signature for the Init() function was the problem. The std::string parameter was causing the debug assertion to fire, my best guess as of right now was because of move semantics but that part I am still not sure on. So there are a couple of ways that I found to fix this.
Method 1:
Make the parameter a const char*. I don't quite like this approach as it then relies on C style strings and if you are trying to write a program in modern C++, this is a huge step backwards.
Method 2:
Make the parameter a const std::string&. Making it a const reference to a string prevents the move semantics (again as far as I know) and the assertion no longer fires. I prefer this fix as it keeps the program in modern C++.
I hope this helps anyone who has similar issues, and be careful with statics and move semantics.

Show error in function if some other function has not run before it

I have two functions in C library that I am making.
One is a setup function, other is a function that does some operations. I want the second operations function to print an error if the setup function has not run before it.
What would be the best way to do this?
Here is what I have in my mind, but I am not sure if that is how it is done.
The setup function:
void setup_function()
{
#ifndef FUNCTION_SETUP
#define FUNCTION_SETUP
a_init();
b_init();
c_init();
#endif
}
And the operations function:
bool operations()
{
#ifdef FUNCTION_SETUP
try
{
/* My code */
return true;
}
catch (...)
{
Serial.println("Error in operations");
return false;
}
#elif Serial.println("Function not setup. Please use setup_function() in void setup()");
#endif
}
#ifndef only checks whether this function was defined somewhere for the compiler and won't affect runtime.
best way to do this is through use of a global variable that changes value once the setup function is executed. if you're defining these functions in classes you could use static data member and setup function
C has a pre-processing command #error that can be used to trigger a stop to the compiling. However, the compilation unit is processed in order, not ran. Some programmes need to just run to see, (which is related to the halting problem.)
The idiomatic way to to runtime checks is with assert, as in this C99 example. (You would #include <cassert> in C++.)
#include <stdbool.h>
#include <assert.h>
static bool is_setup; // Can be optimized away with -D NDEBUG.
static void setup_function(void) {
assert(!is_setup && (is_setup = true));
}
static bool operations(void) {
assert(is_setup);
return true;
}
int main(void) {
//setup_function(); // Triggers `assert` if omitted.
operations();
return 0;
}
However, C++ has techniques that encourage RAII; when possible, one should generally use this to set up an object on acquisition and manage the object throughout it's lifetime.

Call main executable's functions from plugin compiled using Clang

I'm writing a program (macOS, clang++ compiler, only AppleSilicon at the moment) that I can extend later by providing custom plugins (dynamic library, loaded at runtime) which use main program's public interface.
test.hpp - public interface:
#if defined(MAGIC_PLUGIN)
# define MAGIC_EXPORT /* nothing */
#else
# define MAGIC_EXPORT __attribute__((visibility("default")))
#endif
MAGIC_EXPORT
void testCall();
test.cpp - main programm:
#include <stdio.h>
#include <dlfcn.h>
#include "test.hpp"
// Declare a function to call from a loaded plugin
typedef void (* plugin_call_func)(void);
int main(int argc, char** argv) {
// Load library
const char* libraryName = "plugin.dylib";
void* library = dlopen(libraryName, RTLD_NOW);
if (library == nullptr) {
printf("Cannot open library\n");
return 1;
}
// Get function from loaded library
plugin_call_func pluginCall = reinterpret_cast<plugin_call_func>(
dlsym(library, "pluginCall"));
if (pluginCall == nullptr) {
printf("Cannot find the pluginCall function\n");
return 2;
}
// Execute loaded function
pluginCall();
// Forget function and close library
pluginCall = nullptr;
auto libraryCloseResult = dlclose(library);
if (libraryCloseResult != 0) {
printf("Cannot close library\n");
return 3;
}
return 0;
}
// Public function, should be called from a plugin
void testCall() {
printf("Test call\n");
}
plugin.cpp - plugin's source:
#define MAGIC_PLUGIN
#include <stdio.h>
#include "test.hpp"
__attribute__((visibility("default")))
extern "C" void pluginCall(void) {
printf("Plugin call\n");
testCall();
}
First, I compile main app:
clang++ -std=c++20 -fvisibility=hidden -target arm64-apple-macos12 test.cpp -o test
The nm --defined-only test shows these symbols:
0000000100003ee4 T __Z8testCallv
0000000100000000 T __mh_execute_header
0000000100003dcc t _main
Mangled __Z8testCallv is what I need. Everything looks good so far. But then I try to compile the plugin as dynamic library...
clang++ -std=c++20 -fvisibility=hidden -dynamiclib -g -current_version 0.1 -target arm64-apple-macos12 plugin.cpp -o plugin.dylib
and get this error:
Undefined symbols for architecture arm64:
"testCall()", referenced from:
_pluginCall in plugin-38422c.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Well, it's kind of fair, I can understand this, because the dynamic library does not know that testCall is somewhere implemented. So I want to say it that it does not have to worry about testCall's existence.
I tried to research how to do this, looked up man pages, read tons of stack overflow answers, and what I only found that works is adding these flags to linker:
-Wl,-undefined,dynamic_lookup
It works, the library compiles and the app works as expected. But I don't really want to use dynamic_lookup because it will mark every undefined symbol in the library as resolved, which may lead to some bad consequences. I want to tell the linker only about existence of the main program's public symbols.
What am I missing? Is there any better solution than dynamic_lookup?
Your best bet is to manually do the work that's done by the library loader. That is: populating function pointers. After all, the plugin->main binding is already done manually, so doing the same thing the other way around makes sense.
You can make this process essentially transparent by carefully crafting the header shared by the plugin and main application. The only tricky part is handling ODR for plugins that are composed of multiple source files.
Since this is a C++ question, here's what it could look like with a RAII wrapper. The ODR conundrum is handled via the PLUGIN_MAIN macro that should only be defined in one of a plugin's sources.
test_plugin.hpp
using pluginCall_fn = void(*)();
using testCall_fn = void(*)();
#if !defined(MAIN_APPLICATION)
#if defined(PLUGIN_MAIN)
#define EXPORTED_FROM_MAIN __attribute__((visibility("default")))
#else
#define EXPORTED_FROM_MAIN __attribute__((visibility("default"))) extern
#endif
extern "C" {
// Declare symbols provided by the plugin
__attribute__((visibility("default"))) void pluginCall();
// etc...
// Declare/define pointers that will be populated by the main application
EXPORTED_FROM_MAIN testCall_fn testCall;
// etc...
}
#undef EXPORTED_FROM_MAIN
#else // In the main app.
#include <stdexcept>
// Declare "symbols" provided by the main application
void testCall();
// Utility class to load/unload a dynamic library.
// Probably belongs in its own header...
struct loaded_library final {
loaded_library(const char* libName)
: handle_(dlopen(libName, RTLD_NOW)) {
if(!handle_) {
throw std::runtime_error("failed to load plugin");
}
}
loaded_library(const loaded_library&) = delete;
loaded_library& operator=(const loaded_library&) = delete;
loaded_library(loaded_library&& rhs) : handle_(rhs.handle_) {
rhs.handle_ = nullptr;
}
loaded_library& operator=(loaded_library&& rhs) {
handle_ = rhs.handle_;
rhs.handle_ = nullptr;
return *this;
}
~loaded_library() {
if(handle_) {
dlclose(handle_);
}
}
template<typename T>
T get_symbol(const char* symbol) {
T result = reinterpret_cast<T>(dlsym(handle_, symbol));
if(!result) {
throw std::runtime_error("missing symbol");
}
return result;
}
private:
void* handle_;
};
// Plugin interface.
struct loaded_plugin final {
loaded_plugin(const char* libName)
: lib_(libName) {
// Load functions from plugin
pluginCall = lib_.get_symbol<pluginCall_fn>("pluginCall");
// ...
// Assign callbacks to plugin
*lib_.get_symbol<testCall_fn*>("testCall") = &testCall;
// ...
// Call the plugin's init function here if applicable.
}
pluginCall_fn pluginCall;
private:
loaded_library lib_;
};
#endif
plugin.cpp
#define PLUGIN_MAIN
#include "test_plugin.hpp"
#include <stdio.h>
void pluginCall() {
printf("Plugin call\n");
testCall();
}
test.cpp
#define MAIN_APPLICATION
#include "test_plugin.hpp"
int main(int argc, char** argv) {
const char* libraryName = "plugin.dylib";
loaded_plugin plugin(libraryName);
plugin.pluginCall();
}
// Public function, should be called from a plugin
void testCall() {
printf("Test call\n");
}
You may find that this code is a bit on the fragile side of things, since a few different portions of test_plugin.hpp need to be kept in sync.
This can be worked around with the use of X-Macros, at the cost of confusing IDEs and hurting code legibility. I wouldn't go down that road until the APIs in question become unwieldingly large.

What are the major parts of a Tizen application's entry file?

Because Tizen is still not so popular, I couldn't find Tizen application entry file explanation. Could anyone, based on the following example code, explain particular parts of Tizen entry file (Main function return value, #ifdef, args...)?
#include <new>
#include "MultipointTouch.h"
using namespace Tizen::Base;
using namespace Tizen::Base::Collection;
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
_EXPORT_ int OspMain(int argc, char* pArgv[]);
/**
* The entry function of Tizen C++ application called by the operating system.
*/
int
OspMain(int argc, char* pArgv[])
{
AppLog("Application started.");
ArrayList args;
args.Construct();
for (int i = 0; i < argc; i++)
{
args.Add(*(new (std::nothrow) String(pArgv[i])));
}
result r = Tizen::App::Application::Execute(MultipointTouch::CreateInstance, &args);
TryLog(r == E_SUCCESS, "[%s] Application execution failed", GetErrorMessage(r));
args.RemoveAll(true);
AppLog("Application finished.");
return static_cast<int>(r);
}
#ifdef __cplusplus
}
#endif // __cplusplus
#ifdef __cplusplus
extern "C
Not Tizen-specific. What it does is to "[make] a function-name in C++ have 'C' linkage (compiler does not mangle the name) so that client C code can link to (i.e use) your function using a 'C' compatible header file that contains just the declaration of your function." (source).
int OspMain(int argc, char* pArgv[])
OspMain is simply the entry point for a Tizen native application (i.e. the first function in your app that the OS calls when your app starts), much like main or WinMain in other OSs/frameworks.
args
The App Execute method expects the arguments as a list of Strings. So the OspMain function takes care of building that list prior to calling the Execute method; a String is created from each char* in argv, and those Strings are placed in an ArrayList (which is an implementation of the IList interface).
return value
The return type of OspMain is int, but the result code it receives from Execute is of type result, so it casts the result to an int. There are plenty of questions on the topic of C++ casts if you want to read more about them.
In the end, I think there are very few instances where you'd have to care about the Entry file as an app developer. It's automatically created for you by the IDE and not something you'd typically change.

how do I set a debug mode in c++

I would like to set a debug mode so that it prints the log statements only if the debug mode is on. For example if I have code like this
printf("something \n");
.
.
.
perror("something \n");
It only works if the debug flag is on.. I don't want to use "if" statements.
I think there is a clever way to do this using #define or something..
Thank is advance..
#ifdef _DEBUG // or #ifndef NDEBUG
#define LOG_MSG(...) printf(__VA_ARGS__) // Or simply LOG_MSG(msg) printf(msg)
#else
#define LOG_MSG(...) // Or LOG_MSG(msg)
#endif
On non-Debug built LOG_MSG would yeild to nothing. Instead of defining it with raw printf, you can have your custom logging-function, or class-method to be called.
Without going in to specific libraries or solutions, generally people make a logger class or function, and a single debug flag. The debug function checks this flag before calling printf or cout. Then in the rest of your code you simply call your debug function / method.
Here's an example:
class MyDebugger
{
private:
bool m_debug;
public:
MyDebugger();
void setDebug(bool debug);
void debug(const char* message);
};
MyDebugger::MyDebugger()
{
m_debug = false;
}
void MyDebugger::setDebug(bool debug)
{
m_debug = debug;
}
void MyDebugger::debug(const char* message)
{
if(m_debug)
{
cout << message << endl;
}
}
int main(int argc, char** argv)
{
MyDebugger debugger;
debugger.debug("This won't be shown");
debugger.setDebug(true);
debugger.debug("But this will");
return 0;
}
of course this is an incredibly naive implementation. In real logger classes there are many levels for finer-grained control of how much detail gets printed (levels like error, warning, info, and debug to differentiate the importance of the message). They might also let you log to files as well as stdout. Still this should give you a general idea.
In GCC, something like
#define debugprint(...) printf(__VA_ARGS__)
You can do a simple C-style macro definition (especially if you compiler is modern enough to do variable arguments macros, i.e. gcc or VS2005+) doing printf with a check of the debug level which can be a static global variable.
If you go with C++-style class similar to what #Chris suggests, I would make the logging function inline to ensure that when logging is disabled you are not wasting time on calling functions.