Seeking STL-aware c++filt - c++

In my development environment, I'm compiling a code base using GNU C++ 3.4.6. Code is under development, and unfortunately crashes now and then. It's nice to be able to run the traceback through a demangler, and I use c++filt 3.4. The problem comes when functions have a number of STL parameters. Consider
My_callback::operator()(
Status&,
std::set<std::string> const&,
std::vector<My_parameter*> const&,
My_attribute_set const&,
std::vector<My_parameter_base*> const&,
std::vector<My_parameter> const&,
std::set<std::string> const&
)
{
// ...
}
When this function is in the traceback, the mangled output on my platform is:
(_ZN30My_callbackclER11StatusRKSt3setISsSt4lessISsESaISsEERKSt6vectorIP13My_parameterSaISB_EERK17My_attribute_setRKS9_IP18My_parameter_baseSaISK_EERKS9_ISA_SaISA_EES8_+0x76a) [0x13ffdaa]
c++filt kindly demangles it to
(My_callback::operator()(Status&, std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, std::vector<My_parameter*, std::allocator<My_parameter*> > const&, My_attribute_set const&, std::vector<My_parameter_base*, std::allocator<My_parameter_base*> > const&, std::vector<My_parameter, std::allocator<My_parameter> > const&, std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)+0x76a) [0x13ffdaa]
This is the same problem as compiler errors encountered when using templates. However, the STL is a fairly regular and recognizable package of templates. So what I'm hoping is that someone out there has created an enhanced version of c++filt which would dump something closer to the original function signature. Any hints?

STLFilt simplifies and/or reformats long-winded C++ error and warning messages, with a focus on STL-related diagnostics. The result renders many of even the most cryptic diagnostics comprehensible.

Related

Boost.Python - how do you convert a std::map<std::string, std::string> to a dict[str, str]?

I have a Boost.python .cpp that looks like this
BOOST_PYTHON_MODULE(my_module)
{
class_<MyCustomClass>("MyCustomClass")
.def("getDict",
&MyCustomClass::getDict, // This returns std::map<std::string, std::string>
bp::return_value_policy<bp::return_by_value>()
;
}
When I try to call MyCustomClass().getDict(), I get this error:
TypeError: No to_python (by-value) converter found for C++ type: std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >
It looks like Boost doesn't attempt to make this mapping for you by default. How do you let Boost know that it's okay to make that conversion?
At the moment I'm getting around the issue by having MyCustomClass::getDict return a boost::python::dict but, because this API is meant to be used by both C++ and Python users, it'd be much preferred to return the native std::map<std::string, std::string> for the C++ API and do a proper convert in the Python bindings.
I tried adding .def(map_indexing_suite<std::map<std::string, std::string> >()) to the class_ definition but it had no effect. I still get the same TypeError, as shown above.

How to get Tesseract working with CGO on Windows?

I've been trying to get otiai10/gosseract (Go package for Tesseract C++ library) working on Windows without success. As a requirement, gosseract requires the installation of "tesseract-ocr, including library and headers".
The Tesseract Windows compiling documentation mentions the usage of SW and Vcpkg, which to my understanding relies on MSVC and is hence not compatible with Go.
The documentation also mentions the existence of Cygwin packages. I have tried leveraging them by installing tesseract-ocr (5.2.0-1), tesseract-ocr-devel (5.2.0-1), tesseract-ocr-eng (5.00-1) as well as mingw64-x86_64-gcc-g++ and mingw64-x86_64-gcc-core after which I defined the following environment variables:
CGO_CFLAGS=-IC:\cygwin64\usr\include
CGO_CPPFLAGS=-IC:\cygwin64\usr\include
CGO_LDFLAGS=-LC:\cygwin64\lib
PATH=C:\cygwin64\bin;...
CC=C:\cygwin64\bin\x86_64-w64-mingw32-gcc.exe
CXX=C:\cygwin64\bin\x86_64-w64-mingw32-g++.exe
However, trying to compile (through GoLand) an example project (otiai10/ocrserver) still results in linker errors:
GOROOT=C:\Users\REDACTED\go\go1.18rc1 #gosetup
GOPATH=C:\Users\REDACTED\go #gosetup
C:\Users\REDACTED\go\go1.18rc1\bin\go.exe build -o C:\Users\REDACTED\AppData\Local\Temp\GoLand\___go_build_github_com_otiai10_ocrserver.exe github.com/otiai10/ocrserver #gosetup
# github.com/otiai10/gosseract/v2
/usr/lib/gcc/x86_64-w64-mingw32/11/../../../../x86_64-w64-mingw32/bin/ld: $WORK\b133\_x003.o: in function `tesseract::TessBaseAPI::Init(char const*, char const*)':
/cygdrive/c/Users/REDACTED/go/pkg/mod/github.com/otiai10/gosseract/v2#v2.3.1/C:/cygwin64/usr/include/tesseract/baseapi.h:215: undefined reference to `tesseract::TessBaseAPI::Init(char const*, char const*, tesseract::OcrEngineMode, char**, int, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const*, bool)'
/usr/lib/gcc/x86_64-w64-mingw32/11/../../../../x86_64-w64-mingw32/bin/ld: /cygdrive/c/Users/REDACTED/go/pkg/mod/github.com/otiai10/gosseract/v2#v2.3.1/C:/cygwin64/usr/include/tesseract/baseapi.h:215: undefined reference to `tesseract::TessBaseAPI::Init(char const*, char const*, tesseract::OcrEngineMode, char**, int, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const*, bool)'
/usr/lib/gcc/x86_64-w64-mingw32/11/../../../../x86_64-w64-mingw32/bin/ld: /cygdrive/c/Users/REDACTED/go/pkg/mod/github.com/otiai10/gosseract/v2#v2.3.1/C:/cygwin64/usr/include/tesseract/baseapi.h:215: undefined reference to `tesseract::TessBaseAPI::Init(char const*, char const*, tesseract::OcrEngineMode, char**, int, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const*, bool)'
collect2: error: ld returned 1 exit status
How can one get "tesseract-ocr, including library and headers" properly set up on a Windows machine for CGO compatibility?
> go version
go version go1.17 windows/amd64
> C:\cygwin64\bin\x86_64-w64-mingw32-gcc.exe --version
x86_64-w64-mingw32-gcc (GCC) 11.3.0
> C:\cygwin64\bin\x86_64-w64-mingw32-g++.exe --version
x86_64-w64-mingw32-g++ (GCC) 11.3.0
> C:\cygwin64\bin\x86_64-w64-mingw32-ld.exe --version
GNU ld (GNU Binutils) 2.38

How can I suppress a stack-buffer-overflow from AddressSanitizer in gcc

My app is using boost::program_options and it's triggering an AddressSanitizer "stack-buffer-overflow" while generating an error message from an exception.
I'm not worried about the boost bug - the functionality works and this is just in the command line parsing portion of a non-production app. However I'd like to suppress the AddressSanitizer message.
ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffe6ce7070 at pc 0x0000007406cd bp 0x7fffe6ce6fe0 sp 0x7fffe6ce6fd8
READ of size 8 at 0x7fffe6ce7070 thread T0
#0 0x7406cc in std::_Head_base<0ul, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, false>::_M_head(std::_Head_base<0ul, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, false>&) /frc/toolchain6/include/c++/5.3.0/tuple:142
#1 0x7406cc in _M_create_node /frc/toolchain6/include/c++/5.3.0/tuple:347
#2 0x7403fd in std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::piecewise_construct_t const&, std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>&&, std::tuple<>&&) /frc/toolchain6/include/c++/5.3.0/bits/stl_tree.h:2170
#3 0xd5eff8 in boost::program_options::error_with_option_name::substitute_placeholders(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (/home/joe/myapp_workspace/myapp/myapp-debug+0xd5eff8)
#4 0xd5c0dd in boost::program_options::error_with_option_name::what() const (/home/joe/myapp_workspace/myapp/myapp-debug+0xd5c0dd)
#5 0x58addf in main /home/joe/myapp_workspace/myapp/main.cpp:62
#6 0x7fd7e056176c in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
#7 0x436aa0 (/home/joe/myapp_workspace/myapp/myapp-debug+0x436aa0)
I've tried using the ASAN_OPTIONS suppression file method but that only seems to support a very short list of error types (such as "vptr_check" and "leak").
I don't think there's an easy way to suppress this error - Clang version of Asan has blacklisting mechanism but it's context insensitive so you'd have to disable memory checking in all usages of std::string which is highly undesirable.
One option is to use -fsanitize-recover=address compiler flag and add halt_on_error=0 to your ASAN_OPTIONS environment variable (see wiki for details and note that recovery is only supported is relatively new GCC and Clang). This will continue execution after first error. You'll then be able to examine full Asan report and select what interests you.

memory corruption due to #pragma pack error - std map corruption- crashing on insert

I have a project I am working on where I have some strange behavior with the std maps.
I had my own typedef map defined which mapped strings to a pointer of a custom type. The application crashed anytime that I excess the map after I add the first pair to the map.
After a lot of messing around I changed the map to a and moved it to the first call in my application and it still crashes. I have no idea what could be going on. Any help would be appreciated.
Here is the code that crashes at the moment.
LoggerPtr syslogger(Logger::getLogger("CISInterface"));
int main(int argc, char *argv[])
{
typedef std::map<string, string> MyMapDef;
MyMapDef tmpString;
tmpString.insert(MyMapDef::value_type("0000", "d"));
tmpString.insert(MyMapDef::value_type("1111", "d")); //Crashes here.
tmpString.insert(MyMapDef::value_type("2222", "d"));
// std::string configFile;
// int c;
// if(argc < 2)
// {
// //Must have c option
// std::cout << "Usage -c configFileName" << std::endl;
// exit(EXIT_FAILURE);
// }
//Rest of main commented out.
...
And here is the stack trace -
CISInterface Debug [C/C++ Application]
gdb/mi (10/31/12 6:02 PM) (Suspended)
Thread [1] (Suspended: Signal 'SIGSEGV' received. Description: Segmentation fault.)
6 std::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const() 0x00000032fd49c416
5 std::operator< <char, std::char_traits<char>, std::allocator<char> >() basic_string.h:2317 0x0000000000417ec7
4 std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::operator() stl_function.h:230 0x000000000041706f
3 std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_insert_unique() stl_tree.h:1170 0x0000000000415d00
2 std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::insert() stl_map.h:500 0x00000000004150eb
1 main() CISInterface.cpp:29 0x000000000041916d
gdb (10/31/12 6:02 PM)
/home/cillian/workspace/CISInterface/Debug/CISInterface (10/31/12 6:02 PM)
What other areas should I be looking at that could be causing problems. Could it be in the libraries that I'm linking with? I have created a second project with just these lines of code that links with the same libraries (but doesn't have any code that calls into them.) and it doesn't crash.
Problem solved.
Thought I'd add it here on the off chance anyone else ever does the same thing.
I slowly removed files in my project to try and find the offending file. I was thinking that it must be something defined in a header file that was causing issues (like a static). It took a long time but I think I've found it. I had a header file that defines a number of structs. These are serialized to the wire so I had them 1 byte aligned using #pragma pack (push) which I put at the top of the file and #pragma pack (pop) at the bottom. But I then added a couple of #include statements after the first #pragma definition meaning that these includes were aligned incorrectly and caused some nondeterministic behavior. Thanks everyone that had a look. Should probably use the attribute syntax and I wouldn't had the problem. Offending code is below for completeness.
#pragma pack (push)
#pragma pack (1)
#include <string> //Wrong place for includes!
#include <Units.h>
typedef struct
{
....
}
#pragma pack (pop)
Thanks to everyone who had a look at initial problem.

Undefined reference to class?

NetBeans interpret weird my code. In main function I have code:
SequenceAlignment align;
align.Alignment( local, seqs, argv[4], matrix)
But NetBeans show:
cpp:91: undefined reference to `SequenceAlignment::Alignment(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, char*, ScoreMatrix&)'
To be honest I do not know what to think. It works before, but now suddenly it doesn't.
This is a linker error indicating that the linker can't find an implementation for SequenceAlignment::Alignment. Check to see that you indeed have an implementation of this function and that the code containing that implementation is indeed being compiled and linked.