How can i demangle name in MSVC? There's abi::__cxa_demangle function in gcc. In MSDN i've found UnDecorateSymbolName:
http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms681400%28v=vs.85%29.aspx
Unfortunately, this function can't undecorate even such symbol:
#include <Windows.h>
#include <DbgHelp.h>
#include <cstdlib>
#include <iostream>
#include <typeinfo>
int main()
{
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
if (!SymInitialize(GetCurrentProcess(), NULL, TRUE))
{
std::cout << "SymInitialize returned error: " << GetLastError() << '\n';
return EXIT_FAILURE;
}
class Foo {};
Foo instance;
const char* decorated_name = typeid(instance).name();
char undecorated_name[1024];
if (!UnDecorateSymbolName(decorated_name, undecorated_name, sizeof(undecorated_name) / sizeof(*undecorated_name), UNDNAME_COMPLETE))
{
std::cout << "UnDecorateSymbolName returned error: " << GetLastError() << '\n';
return EXIT_FAILURE;
}
std::cout << "Decorated name: " << decorated_name << '\n'
<< "Undecorated name: " << undecorated_name << '\n';
}
Output
Decorated name: ?AVFoo#?4?main#
Undecorated name: ?AVFoo#?4?main#
If i am doing it wrong?
I've heard somewhere about _unDName function, but i can't find any example with it. In which header file it is defined?
Visual studio already shipped a utility called undname. For my VS2010 and VS2013 install, it's installed to
%VSINSTALL%\vc\bin directory.
And for x64 platform, in
%VSINSTALL%\vc\amd64\bin directory.
The example usage is:
D:\work\VS2013>undname "?static_x#?1??getX##YAAAUX##XZ#4U2#A"
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "?static_x#?1??getX##YAAAUX##XZ#4U2#A"
is :- "struct X `struct X & __cdecl getX(void)'::`2'::static_x"
Another way to get the demangled name is use /FAsc /Faoutput.asm compiler option, which will produce the assembly list, in which each mangled name is commented with it's demangled name. See This link for reference.
It seems UndecorateSymbolName/__unDName can't handle function-local names. If you move the class definition to the global scope, .name() will return already demangled name (use .raw_name() to get the mangled name).
To demangle the (global) raw name manually, you need two changes to your code:
1) skip the leading period in the mangled name (i.e. start at the '?').
2) instead of 0, use the flag value 0x2800 (UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY).
I found this out from the CRT sources of VS2012:
if ((pTmpUndName = __unDName(NULL, (this->_M_d_name)+1, 0,
&_malloc_base, &_free_base,
UNDNAME_32_BIT_DECODE | UNDNAME_TYPE_ONLY)) == NULL)
Update for Visual Studio 2019.
(1) typeid(instance).name() - used in the request - already returns the undecorated name: further demangling is not required in this case
(2) the command UNDNAME.EXE, provided in the bin folders, does not work correctly, even if we take off the initial dot. For example ".?AVFoo#?1??main##YAHXZ#" is unmangled as " ?? int __cdecl main(void)'::2'::AVFoo", giving an invalid name AVFoo. The correct name must be Foo
(3) the dbghelp API UnDecorateSymbolName() does not work either
(4) the correct code can be deduced from the assembly generated by the compiler for the directive typeid()
Here is a little program which will undecorate correctly all the C++ mangled symbols:
// compile as: cl -W3 und.c
#include <windows.h>
#include "dbghelp.h"
#include <stdio.h>
#pragma comment(lib, "dbghelp.lib")
extern char *__unDName(char*, const char*, int, void*, void*, int);
int
main(int argc, char **argv)
{
const char *decorated_name = 0;
char undecorated_name[1024];
if (argc == 2) decorated_name = argv[1];
else {
printf("usage: %s <decorated_name>\n", argv[0]);
return 1;
}
__unDName(undecorated_name, decorated_name+1, 1024, malloc, free, 0x2800);
printf("Decorated name: %s\n", decorated_name);
printf("Undecorated name: %s\n", undecorated_name);
return 0;
}
For example:
und ".?AVFoo#?1??main##YAHXZ#"
Decorated name: .?AVFoo#?1??main##YAHXZ#
Undecorated name: class int __cdecl main(void)'::2'::Foo
UndecorateSymbolName also does not work as my expectation. If you want to iterate over members of struct or class, use boost fusion to implement reflection in C++.
Related
I can not get the gnu extension to elf with indirect functions to work with dladdr.
In the example below fabs and sin are two dynamic functions in libm, where sin is also an indirect function. Looking up fabs from its pointer works well, but sin is not found. I have tried various flags to dlopen and -rdynamic without success.
The debugger shows how sin is evaluated from from a gnu-indirect-function variable to __sin_avx.
Am I missing something here or are indirect functions not supported by dladdr?
/*
compiled with g++-5 -fPIC -ldl
*/
#include <cmath>
#include <dlfcn.h>
#include <iostream>
char const * name (void * arg)
{
void * h = dlopen (NULL, RTLD_LAZY);
if (h)
{
Dl_info res;
int status = dladdr (arg, & res);
dlclose (h);
if (status && res.dli_sname && arg == res.dli_saddr)
return res.dli_sname;
}
return "";
}
int main ()
{
std::cout << fabs (0.0) << " " << name ((void *) fabs) << std::endl; // found
std::cout << sin (0.0) << " " << name ((void *) sin ) << std::endl; // not found
}
Am I missing something here or are indirect functions not supported by dladdr?
Ok, this one was interesting.
So ifuncs work by replacing original function address (in this case sin) with the one it's resolved to by dynamic linker on current platform. sin can be resolved to one of 4 implementations depending on CPU capabilities:
libm_ifunc (__sin, (HAS_ARCH_FEATURE (FMA4_Usable) ? __sin_fma4 :
HAS_ARCH_FEATURE (AVX_Usable)
? __sin_avx : __sin_sse2));
weak_alias (__sin, sin)
Now each of __sin_XXX is an internal Glibc function which is not exported from libm.so and that's why dladdr fails to find it.
So the answer is basically no, dladdr does not work well with ifuncs...
manages to work if you remove -fPIC
This happens because whenever you compile w/o -fPIC compiler knows that current source file will go to main executable and so runtime function address is guaranteed to resolve to executable's PLT entry. So instead of loading it from GOT, it simply passes PLT address to name and dladdr then happily locates sin in executable's symtab.
EDIT:
Confirmed by Glibc folks here.
There are similar questions here but they don't quite answer my question:
When to use __declspec(dllexport) in C++
Why do I need __declspec(dllexport) to make some functions accessible from ctypes?
When I cross-compile a DLL from Mac OS X using MinGW and wclang, why does my DLL work fine without using __declspec?
The MinGW DLL sample docs, and every reference I see to doing this, say to use __declspec(dllexport) before function declarations. Yet none of the code in my 9,000-line library uses it, and the DLL works great!
For example, here's a contrived example library built in the same way:
#include <stdio.h>
extern "C" {
int hello(const char* name) {
printf("Hello, %s!\n", name);
return 0;
}
}
Compiled with this on Mac OS X 10.10.3:
w32-clang++ test.cpp -shared -o test.dll
Produces a fine-looking DLL:
And my Windows application:
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
typedef int(*hellofn)(const char*);
int _tmain(int argc, _TCHAR* argv[])
{
DWORD err;
HINSTANCE dll = LoadLibrary(L"E:\\test.dll");
if (!dll) {
err = GetLastError();
std::cout << "Can't load library: " << err << std::endl;
return 1;
}
hellofn hello = (hellofn)GetProcAddress(dll, "hello");
if (!hello) {
err = GetLastError();
std::cout << "Could not load the function: " << err << std::endl;
return 2;
}
int ret = hello("nerd");
std::cout << "hello() returned " << ret << std::endl;
return 0;
}
Works great:
Am I shooting myself in the foot somehow, or is there some magic that I'm not seeing? I'm thinking that wclang (MinGW+clang) knows to use __stdcall automatically somehow and doesn't mangle the function names?
No, you do not need __declspec(dllexport), when building a DLL with MinGW; (in fact, I frequently omit it myself). The caveat is that, if just one symbol to be included in the DLL is so decorated, then all others you wish to have exported must be likewise decorated, (unless you pass the --export-all-symbols option to the linker when you build the DLL).
If you include only undecorated symbols, then all global symbols will be exported, just as if --export-all-symbols were specified by default.
However, this has nothing whatsoever to do with __stdcall vs. __cdecl calling conventions, or name mangling; it is solely a determinant of the visibility of symbols in the DLL's export table. If you don't declare your functions to be __stdcall or __cdecl, then they will be __cdecl by default; that's no problem, provided both providing DLL and caller agree on that convention. Similarly, if both agree on any name mangling convention, (which normally means that, in the case of C++ in particular, they both used the same compiler at build time), then there will be no linking problems.
I'm trying to call some C++ functions through a function pointer table which is exported as a C symbol from a shared object. The code is actually working but Clang's undefined behavior sanitizer (= UBSan) sees the call I made is illegal as follows:
==11410==WARNING: Trying to symbolize code, but external symbolizer is not initialized!
path/to/HelloWorld.cpp:25:13: runtime error: call to function (unknown) through pointer to incorrect function type 'foo::CBar &(*)()'
(./libFoo.so+0x20af0): note: (unknown) defined here
Due to Clang's undefined behavior sanitizer, it is legal to indirectly call a function which returns a reference of a C++ standard class object through a function pointer but it's illegal for a user-defined class. Somebody could you please tell me what's wrong with it?
I've been trying to build the project on Ubuntu 14.04 with Clang-llvm 3.4-1ubuntu3 and CMake 2.8.12.2. To reproduce the phenomenon, please place the following 5 files in the same directory and invoke build.sh. It will create a makefile and build the project, and run the executable.
Foo.h
#ifndef FOO_H
#define FOO_H
#include <string>
//
#define EXPORT __attribute__ ((visibility ("default")))
namespace foo {
class CBar
{
// empty
};
class CFoo
{
public:
static CBar& GetUdClass();
static std::string& GetStdString();
};
// function pointer table.
typedef struct
{
CBar& (*GetUdClass)();
std::string& (*GetStdString)();
} fptr_t;
//! function pointer table which is exported.
extern "C" EXPORT const fptr_t FptrInFoo;
}
#endif
Foo.cpp
#include "Foo.h"
#include <iostream>
using namespace std;
namespace foo
{
// returns reference of a static user-defined class object.
CBar& CFoo::GetUdClass()
{
cout << "CFoo::GetUdClass" << endl;
return *(new CBar);
}
// returns reference of a static C++ standard class object.
std::string& CFoo::GetStdString()
{
cout << "CFoo::GetStdString" << endl;
return *(new string("Hello"));
}
// function pointer table which is to be dynamically loaded.
const fptr_t FptrInFoo = {
CFoo::GetUdClass,
CFoo::GetStdString,
};
}
HelloWorld.cpp
#include <iostream>
#include <string>
#include <dirent.h>
#include <dlfcn.h>
#include "Foo.h"
using namespace std;
using namespace foo;
int main()
{
// Retrieve a shared object.
const string LibName("./libFoo.so");
void *pLibHandle = dlopen(LibName.c_str(), RTLD_LAZY);
if (pLibHandle != 0) {
cout << endl;
cout << "Info: " << LibName << " found at " << pLibHandle << endl;
// Try to bind a function pointer table:
const string SymName("FptrInFoo");
const fptr_t *DynLoadedFptr = static_cast<const fptr_t *>(dlsym(pLibHandle, SymName.c_str()));
if (DynLoadedFptr != 0) {
cout << "Info: " << SymName << " found at " << DynLoadedFptr << endl;
cout << endl;
// Do something with the functions in the function table pointer.
DynLoadedFptr->GetUdClass(); // Q1. Why Clang UBSan find this is illegal??
DynLoadedFptr->GetStdString(); // Q2. And why is this legal??
} else {
cout << "Warning: Not found symbol" << endl;
cout << dlerror() << endl;
}
} else {
cout << "Warning: Not found library" << endl;
cout << dlerror() << endl;
}
cout << endl;
return 0;
}
CMakeLists.txt
project (test)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath,$ORIGIN")
add_library(Foo SHARED Foo.cpp)
add_executable(HelloWorld HelloWorld.cpp)
target_link_libraries (HelloWorld dl)
build.sh
#!/bin/bash
# 1. create a build directory.
if [ -d _build ]; then
rm -rf _build
fi
mkdir _build
cd _build
# 2. generate a makefile.
CC=clang CXX=clang++ CXXFLAGS="-fvisibility=hidden -fsanitize=undefined -O0 -g3" cmake ..
# 3. build.
make
# 4. and run the executable.
./HelloWorld
I've been trying to find a clue to dig into the issue and realized the issue was caught by "function" option of the sanitizer (-fsanitize=function) but it's not so much documented. I'd appreciate if you guys could give me a reasonable explanation for such a runtime error message which looks like coming from another planet. Thanks.
What was Clang pointing out as "unknown" in the output?
Below is the output from addr2line to check what was "unknown" for the sanitizer:
$ addr2line -Cfe _build/libFoo.so 0x20af0
foo::CFoo::GetUdClass()
path/to/Foo.cpp:12
Hmm, it really looks like the function I was expecting to call for me. Can you guess how did it look different for Clang?
CBar's typeinfo needs to have default visibility for the function's type be considered the same by Clang on Linux across the executable and the dynamic library; change Foo.h to:
class EXPORT CBar
{
...
}
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.
After years of using the big ugly MFC ASSERT macro, I have finally decided to ditch it and create the ultimate ASSERT macro.
I am fine with getting the file and line number, and even the expression that failed. I can display a messagebox with these in, and Abort/Retry/Cancel buttons.
And when I press Retry the VS debugger jumps to the line containing the ASSERT call (as opposed to the disassembly somewhere like some other ASSERT functions). So it's all pretty much working.
But what would be really cool would be to display the name of the function that failed.
Then I can decide whether to debug it without trying to guess what function it's in from the filename.
e.g. if I have the following function:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
ASSERT(lpCreateStruct->cx > 0);
...
}
Then when the ASSERT fires, the messagebox would show something like:
Function = CMainFrame::OnCreate
So, what's the simplest way of finding out the current function name, at runtime?
It should not use MFC or the .NET framework, even though I do use both of these.
It should be as portable as possible.
Your macro can contain the __FUNCTION__ macro.
Make no mistake, the function name will be inserted into the expanded code at compile time, but it will be the correct function name for each call to your macro. So it "seems like" it happens in run-time ;)
e.g.
#define THROW_IF(val) if (val) throw "error in " __FUNCTION__
int foo()
{
int a = 0;
THROW_IF(a > 0); // will throw "error in foo()"
}
The C++ preprocessor macro __FUNCTION__ gives the name of the function.
Note that if you use this, it's not really getting the filename, line number, or function name at runtime. Macros are expanded by the preprocessor, and compiled in.
Example program:
#include <iostream>
void function1()
{
std::cout << "my function name is: " << __FUNCTION__ << "\n";
}
int main()
{
std::cout << "my function name is: " << __FUNCTION__ << "\n";
function1();
return 0;
}
output:
my function name is: main
my function name is: function1
There's no standard solution. However, BOOST_CURRENT_FUNCTION is portable for all practical purposes. The header does not not depend on any of the other Boost headers, so can be used standalone if the overhead of the whole library is unacceptable.
__FUNCTION__ or __FUNC__ or __PRETTY_FUNCTION__
http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx
http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
In GCC you can use the __PRETTY_FUNCTION__ macro.
Microsoft also have an equivalent __func__ macro although I don't have that available to try.
e.g. to use __PRETTY_FUNCTION__ putting something like this at the beginning of your functions and you'll get a complete trace
void foo(char* bar){
cout << __PRETTY_FUNCTION__ << std::endl
}
which will output
void foo(char* bar)
You also have the __FILE__ and __LINE__ macros available under all standard c/c++ compilers if you want to output even more information.
In practice I have a special debugging class which I use instead of cout. By defining appropriate environment variables I can get a full program trace. You could do something similar. These macros are incredibly handy and it's really great to be able to turn on selective debugging like this in the field.
EDIT: apparently __func__ is part of the standard? didn't know that. Unfortunately, it only gives the function name and not the parameters as well. I do like gcc's __PRETTY_FUNC__ but it's not portable to other compilers.
GCC also supports __FUNCTION__.
You can use the __FUNCTION__ macro which at compile time will be expanded to the name of the function.
Here's an example of how to use it in an assert macro.
#define ASSERT(cond) \
do { if (!(cond)) \
MessageBoxFunction("Failed: %s in Function %s", #cond, __FUNCTION__);\
} while(0)
void MessageBoxFunction(const char* const msg, ...)
{
char szAssertMsg[2048];
// format args
va_list vargs;
va_start(vargs, msg);
vsprintf(szAssertMsg, msg, vargs);
va_end(vargs);
::MessageBoxA(NULL, szAssertMsg, "Failed Assertion", MB_ICONERROR | MB_OK);
}
C++20 std::source_location::function_name
No macros are needed now that we have proper standardization:
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.
you can easily use func.
it will take back you current function name at runtime which raised the exception.
usage:
cout << __func__ << ": " << e.what();