Protobuf with C++ plugins - c++

We're working on a relatively large-scale C++ project where we chose at the very beginning to use protobuf as our Lingua Franca for stored and transmitted data.
We had our first problem because of end-of-program memory leaks due to the protobuf generated classes metadata that are stored as static pointer, allocated during the first call to the constructor and never deallocated. We found a nice function provide by Mr. Google to do this clean-up:
google::protobuf::ShutdownProtobufLibrary();
Works fine except there is no symmetric call, so once it's done you can no longer use anything . You have to do that exactly one time in your executable. We did what any lazy developper would have done:
struct LIBPROTOBUF_EXPORT Resource
{
~Resource()
{
google::protobuf::ShutdownProtobufLibrary();
}
};
bool registerShutdownAtExit()
{
static Resource cleaner;
return true;
}
And we added in the protobuf generation of cc files a:
static bool protobufResource = mlv::protobuf::registerShutdownAtExit();
It worked fine for several months.
Then we added the support for dynamically loadable plugins (dlls) in our tool. Some of them using protobuf. Unloading of the plugins worked fine, but when more than one of them used protobuf, we had a nice little crash when unloading the last one.
The reason: the last to unload would destroy the cleaner instance, itself trying to google::protobuf::ShutdownProtobufLibrary(), itself trying to destroy metadata of unloaded types... CRASH.
Long story short: are we condemned to either have lots of "normal" memory leaks or a crash when closing our tool. Does anyone have experienced the same problem and found a better solution? Is my diagnosis bad?

Like johnathon suggested in his comment, use a reference counting scheme, or register your destruction routine with atexit. Such a routine is free-standing, but that could work fine for your case.
Relevant documentation:
MSDN
POSIX
Edit: You're right, it's basically the same thing. Didn't think this through.
Another suggestion: Use a global resource singleton for all protobuf-using plugins. This one has a global destructor, which is only registered when a plugin first uses the protobuf library. Or just set a flag whenver it's used, then call ShutdownProtobufLibrary only if the flag is set.

Related

constructing completely private and anonymous static singleton

I was trying to think of a way how to deal with C libraries that expect you to globally initialize them and I came up with this:
namespace {
class curl_guard {
public:
curl_guard()
{
puts("curl_guard constructor");
// TODO: curl_global_init
}
~curl_guard()
{
puts("curl_guard destructor");
// TODO: curl_global_cleanup
}
};
curl_guard curl{}; // nothing is ever printed to terminal
}
But when I link this into an executable and run it, there's no output, because it is optimized out (verified with objdump), even in debug build. As I understand, this is intended, because this type is never accessed in any way. Is there any way to mark it so that it is not excluded? Preferably without making it accessible to the user of the library. I'd prefer a general solution, but GCC-only also works for my purposes.
I am aware of typical singleton patterns, but I think this is a special case where none of them apply, because I never want to access this even from internals, just simply have a class tucked away which has one simple job of initializing and deinitializing a C library which is caused by the library being linked in and not something arbitrary like "just don't forget to construct this in main" which is as useful as going back to writing C code.
The real solution was pretty simple - the code can't be separate and needs to be in one of compilation units that are used by the user of the library.
libcurl needs to be initialized globally, and initialization is NOT thread safe, because libraries it depends on also cannot be initialized in thread-safe manner, so it is one of those things where global pre-main initialization is not only convenient, but useful. I in fact am using several other libraries which are like that, and I separate them from libraries that do use threads in the background, by putting those in the main as opposed to pre-main.
And while there are some concerns with doing something like this at all, that's exactly what I need, including library aborting before main even runs if it's installed improperly.
Sure, it's "good practice" to ignore critical errors just to please the users of libraries who insist on libraries aborting being oh so terrible, but I'm sure noone likes to know that in next 50 seconds, they will be dead due to flying vertically downwards due to something that could've been found and fixed early.

AccessViolationException reading memory allocated in C++ application from C++/CLI DLL

I have a C++ client to a C++/CLI DLL, which initializes a series of C# dlls.
This used to work. The code that is failing has not changed. The code that has changed is not called before the exception is thrown. My compile environment has changed, but recompiling on a machine with an environment similar to my old one still failed. (EDIT: as we see in the answer this is not entirely true, I was only recompiling the library in the old environment, not the library and client together. The client projects had been upgraded and couldn't easily go back.)
Someone besides me recompiled the library, and we started getting memory management issues. The pointer passed in as a String must not be in the bottom 64K of the process's address space. I recompiled it, and all worked well with no code changes. (Alarm #1) Recently it was recompiled, and memory management issues with strings re-appeared, and this time they're not going away. The new error is Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I'm pretty sure the problem is not located where I see the exception, the code didn't change between the successful and failing builds, but we should review that to be complete. Ignore the names of things, I don't have much control over the design of what it's doing with these strings. And sorry for the confusion, but note that _bridge and bridge are different things. Lots of lines of code missing because this question is already too long.
Defined in library:
struct Config
{
std::string aye;
std::string bee;
std::string sea;
};
extern "C" __declspec(dllexport) BridgeBase_I* __stdcall Bridge_GetConfiguredDefaultsImplementationPointer(
const std::vector<Config> & newConfigs, /**< new configurations to apply **/
std::string configFolderPath, /**< folder to write config files in **/
std::string defaultConfigFolderPath, /**< folder to find default config files in **/
std::string & status /**< output status of config parse **/
);
In client function:
GatewayWrapper::Config bridge;
std::string configPath("./config");
std::string defaultPath("./config/default");
GatewayWrapper::Config gwtransport;
bridge.aye = "bridged.dll";
bridge.bee = "1.0";
bridge.sea = "";
configs.push_back(bridge);
_bridge = GatewayWrapper::Bridge_GetConfiguredDefaultsImplementationPointer(configs, configPath, defaultPath, status);
Note that call to library that is crashing is in the same scope as the vector declaration, struct declaration, string assignment and vector push-back
There are no threading calls in this section of code, but there are other threads running doing other things. There is no pointer math here, there are no heap allocations in the area except perhaps inside the standard library.
I can run the code up to the Bridge_GetConfiguredDefaultsImplementationPointer call in the debugger, and the contents of the configs vector look correct in the debugger.
Back in the library, in the first sub function, where the debugger don't shine, I've broken down the failing statement into several console prints.
System::String^ temp
List<CConfig^>^ configs = gcnew List<CConfig ^>((INT32)newConfigs.size());
for( int i = 0; i< newConfigs.size(); i++)
{
std::cout << newConfigs[i].aye<< std::flush; // prints
std::cout << newConfigs[i].aye.c_str() << std::flush; // prints
temp = gcnew System::String(newConfigs[i].aye.c_str());
System::Console::WriteLine(temp); // prints
std::cout << "Testing string creation" << std::endl; // prints
std::cout << newConfigs[i].bee << std::flush; // crashes here
}
I get the same exception on access of bee if I move the newConfigs[i].bee out above the assignment of temp or comment out the list declaration/assignment.
Just for reference that the std::string in a struct in a vector should have arrived at it's destination ok
Is std::vector copying the objects with a push_back?
std::string in struct - Copy/assignment issues?
http://www.cplusplus.com/reference/vector/vector/operator=/
Assign one struct to another in C
Why this exception is not caught by my try/catch
https://stackoverflow.com/a/918891/2091951
Generic AccessViolationException related questions
How to handle AccessViolationException
Programs randomly getting System.AccessViolationException
https://connect.microsoft.com/VisualStudio/feedback/details/819552/visual-studio-debugger-throws-accessviolationexception
finding the cause of System.AccessViolationException
https://msdn.microsoft.com/en-us/library/ms164911.aspx
Catching access violation exceptions?
AccessViolationException when using C++ DLL from C#
Suggestions in above questions
Change to .net 3.5, change target platform - these solutions could have serious issues with a large mult-project solution.
HandleProcessCorruptedStateExceptions - does not work in C++, this decoration is for C#, catching this error could be a very bad idea anyway
Change legacyCorruptedStateExceptionsPolicy - this is about catching the error, not preventing it
Install .NET 4.5.2 - can't, already have 4.6.1. Installing 4.6.2 did not help. Recompiling on a different machine that didn't have 4.5 or 4.6 installed did not help. (Despite this used to compile and run on my machine before installing Visual Studio 2013, which strongly suggests the .NET library is an issue?)
VSDebug_DisableManagedReturnValue - I only see this mentioned in relation to a specific crash in the debugger, and the help from Microsoft says that other AccessViolationException issues are likely unrelated. (http://connect.microsoft.com/VisualStudio/feedbackdetail/view/819552/visual-studio-debugger-throws-accessviolationexception)
Change Comodo Firewall settings - I don't use this software
Change all the code to managed memory - Not an option. The overall design of calling C# from C++ through C++/CLI is resistant to change. I was specifically asked to design it this way to leverage existing C# code from existing C++ code.
Make sure memory is allocated - memory should be allocated on the stack in the C++ client. I've attempted to make the vector be not a reference parameter, to force a vector copy into explicitly library controlled memory space, did not help.
"Access violations in unmanaged code that bubble up to managed code are always wrapped in an AccessViolationException." - Fact, not a solution.
but it was the mismatch, not the specific version that was the problem
Yes, that's black letter law in VS. You unfortunately just missed the counter-measures that were built into VS2012 to turn this mistake into a diagnosable linker error. Previously (and in VS2010), the CRT would allocate its own heap with HeapAlloc(). Now (in VS2013), it uses the default process heap, the one returned by the GetProcessHeap().
Which is in itself enough to trigger an AVE when you run your app on Vista or higher, allocating memory from one heap and releasing it from another triggers an AVE at runtime, a debugger break when you debug with the Debug Heap enabled.
This is not where it ends, another significant issue is that the std::string object layout is not the same between the versions. Something you can discover with a little test program:
#include <string>
#include <iostream>
int main()
{
std::cout << sizeof(std::string) << std::endl;
return 0;
}
VS2010 Debug : 32
VS2010 Release : 28
VS2013 Debug : 28
VS2013 Release : 24
I have a vague memory of Stephen Lavavej mentioning the std::string object size reduction, very much presented as a feature, but I can't find it back. The extra 4 bytes in the Debug build is caused by the iterator debugging feature, it can be disabled with _HAS_ITERATOR_DEBUGGING=0 in the Preprocessor Definitions. Not a feature you'd quickly want to throw away but it makes mixing Debug and Release builds of the EXE and its DLLs quite lethal.
Needless to say, the different object sizes seriously bytes when the Config object is created in a DLL built with one version of the standard C++ library and used in another. Many mishaps, the most basic one is that the code will simply read the Config::bee member from the wrong offset. An AVE is (almost) guaranteed. Lots more misery when code allocates the small flavor of the Config object but writes the large flavor of std::string, that randomly corrupts the heap or the stack frame.
Don't mix.
I believe 2013 introduced a lot of changes in the internal data formats of STL containers, as part of a push to reduce memory usage and improve perf. I know vector became smaller, and string is basically a glorified vector<char>.
Microsoft acknowledges the incompatibility:
"To enable new optimizations and debugging checks, the Visual Studio
implementation of the C++ Standard Library intentionally breaks binary
compatibility from one version to the next. Therefore, when the C++
Standard Library is used, object files and static libraries that are
compiled by using different versions can't be mixed in one binary (EXE
or DLL), and C++ Standard Library objects can't be passed between
binaries that are compiled by using different versions."
If you're going to pass std::* objects between executables and/or DLLs, you absolutely must ensure that they are using the same version of the compiler. It would be well-advised to have your client and its DLLs negotiate in some way at startup, comparing any available versions (e.g. compiler version + flags, boost version, directx version, etc.) so that you catch errors like this quickly. Think of it as a cross-module assert.
If you want to confirm that this is the issue, you could pick a few of the data structures you're passing back and forth and check their sizes in the client vs. the DLLs. I suspect your Config class above would register differently in one of the fail cases.
I'd also like to mention that it is probably a bad idea in the first place to use smart containers in DLL calls. Unless you can guarantee that the app and DLL won't try to free or reallocate the internal buffers of the other's containers, you could easily run into heap corruption issues, since the app and DLL each have their own internal C++ heap. I think that behavior is considered undefined at best. Even passing const& arguments could still result in reallocation in rare cases, since const doesn't prevent a compiler from diddling with mutable internals.
You seem to have memory corruption. Microsoft Application Verifier is invaluable in finding corruption. Use it to find your bug:
Install it to your dev machine.
Add your exe to it.
Only select Basics\Heaps.
Press Save. It doesn't matter if you keep application verifier open.
Run your program a few times.
If it crashes, debug it and this time, the crash will point to your problem, not just some random location in your program.
PS: It's a great idea to have Application Verifier enabled at all times for your development project.

Where do I define code to release resources allocated in a C Python module init function?

Extending Python with C or C++ involves defining a shared library which exposes an initialization function along the lines of
PyMODINIT_FUNC
initspam(void)
{
(void) Py_InitModule("spam", SpamMethods);
}
Assuming I allocate resources here, like allocating a global object via
g_bookkeeping = new Bookkeeping;
What would be the correct place to write the corresponding delete statement? There doesn't seem to be any hook for noticing that a module is unloaded, or is there?
I briefly considered using a global object, like
Bookkeeping g_bookkeeping;
...but I'd like to have precise control over when that object is constructed or destructed.
The Python documentations talks about finalization and mentions a Py_Finalize() call which -- at least in Python 2.x -- internally calls PyImport_Cleanup. However, that doesn't seem to do much as far as customizing the module shutdown goes.
A message to an issue from 2010 states for the version of Python you're using:
[...]
Please accept that Python indeed does not support unloading modules for severe, fundamental, insurmountable, technical problems, in 2.x.
[...]
Supporting unloading will be (and was) a multi-year project. Don't expect any results in the next five years.
The documentation for Py_Finalize() also mentions as Bugs and caveats:
Dynamically loaded extension modules loaded by Python are not unloaded.

How can I create objects based on dump file memory in a WinDbg extension?

I work on a large application, and frequently use WinDbg to diagnose issues based on a DMP file from a customer. I have written a few small extensions for WinDbg that have proved very useful for pulling bits of information out of DMP files. In my extension code I find myself dereferencing c++ class objects in the same way, over and over, by hand. For example:
Address = GetExpression("somemodule!somesymbol");
ReadMemory(Address, &addressOfPtr, sizeof(addressOfPtr), &cb);
// get the actual address
ReadMemory(addressOfObj, &addressOfObj, sizeof(addressOfObj), &cb);
ULONG offset;
ULONG addressOfField;
GetFieldOffset("somemodule!somesymbolclass", "somefield", &offset);
ReadMemory(addressOfObj+offset, &addressOfField, sizeof(addressOfField), &cb);
That works well, but as I have written more extensions, with greater functionality (and accessing more complicated objects in our applications DMP files), I have longed for a better solution. I have access to the source of our own application of course, so I figure there should be a way to copy an object out of a DMP file and use that memory to create an actual object in the debugger extension that I can call functions on (by linking in dlls from our application). This would save me the trouble of pulling things out of the DMP by hand.
Is this even possible? I tried obvious things like creating a new object in the extension, then overwriting it with a big ReadMemory directly from the DMP file. This seemed to put the data in the right fields, but freaked out when I tried to call a function. I figure I am missing something...maybe c++ pulls some vtable funky-ness that I don't know about? My code looks similar to this:
SomeClass* thisClass = SomeClass::New();
ReadMemory(addressOfObj, &(*thisClass), sizeof(*thisClass), &cb);
FOLLOWUP: It looks like POSSIBLY ExtRemoteTyped from EngExtCpp is what I want? Has anyone successfully used this? I need to google up some example code, but am not having much luck.
FOLLOWUP 2: I am pursuing two different routes of investigation on this.
1) I am looking into ExtRemoteTyped, but it appears this class is really just a helper for the ReadMemory/GetFieldOffset calls. Yes, it would help speed things up ALOT, but doesn't really help when it comes to recreating an object from a DMP file. Although documentation is slim, so I might be misunderstanding something.
2) I am also looking into trying to use ReadMemory to overwrite an object created in my extension with data from the DMP file. However, rather than using sizeof(*thisClass) as above, I was thinking I would only pick out the data elements, and leave the vtables untouched.
Interesting idea, but this would have a hope of working only on the simplest of objects. For example, if the object contains pointers or references to other objects (or vtables), those won't copy very well over to a new address space.
However, you might be able to get a 'proxy' object to work that when you call the proxy methods they make the appropriate calls to ReadMemory() to get the information. This sounds to be a fair bit of work, and I'd think it would have to be more or less a custom set of code for each class you wanted to proxy. There's probably a better way to go about this, but that's what came to me off the top of my head.
I ended up just following my initial hunch, and copying over the data from the dmp file into a new object. I made this better by making remote wrapper objects like this:
class SomeClassRemote : public SomeClass
{
protected:
SomeClassRemote (void);
SomeClassRemote (ULONG inRemoteAddress);
public:
static SomeClassRemote * New(ULONG inRemoteAddress);
virtual ~SomeClassRemote (void);
private:
ULONG m_Address;
};
And in the implementation:
SomeClassRemote::SomeClassRemote (ULONG inRemoteAddress)
{
ULONG cb;
m_Address = inRemoteAddress;
// copy in all the data to the new object, skipping the virtual function tables
ReadMemory(inRemoteAddress + 0x4, (PVOID) ((ULONG)&(*this) +0x4), sizeof(SomeClass) - 4, &cb);
}
SomeClassRemote::SomeClassRemote(void)
{
}
SomeClassRemote::~SomeClassRemote(void)
{
}
SomeClassRemote* SomeClassRemote::New(ULONG inRemoteAddress)
{
SomeClassRemote*x = new SomeClassRemote(inRemoteAddress);
return (x);
}
That is the basics, but then I add specific overrides in as necessary to grab more information from the dmp file. This technique allows me to pass these new remote objects back into our original source code for processing in various utility functions, cause they are derived from the original class.
It sure SEEMS like I should be able to templatize this somehow... but there always seems to be SOME reason that each class is implemented SLIGHTLY differently, for example some of our more complicated objects have a couple vtables, both of which have to be skipped.
I know getting memory dumps have always been the way to get information for diagnosing, but with ETW its lot more easy and you get a information along with call stacks which include information system calls and user code. MS has been doing this for all their products including Windows and VS.NET.
It is a non-intrusive way of debugging. I have done same debugging for very long and now with ETW I am able to solve most of customer issues without spending lot of time inside the debugger. These are my two cents.
I approached something similar when hacking a gdi leak tracer extension for windbg. I used an stl container for data storage in the client and needed a way to traverse the data from the extension. I ended up implementing the parts of the hash_map I needed directly on the extension side using ExtRemoteTyped which was satisfactory but took me awhile to figure out ;o)
Here is the source code.

Do c++ static libraries without mfc that are linked to an MFC project throw bad_alloc or CMemoryException*?

I'm working on a large, aging code base for an MFC app. The code has been worked on by many developers over time, and as a result, we have three different ways throughout the code of dealing with the possibility of an allocation failure with new.
The first way is to test for NULL on the result of new. We don't use nothrownew.obj so this is clearly an error that needs to be cleaned up.
The second is to catch CMemoryException* (yes, C++ exceptions are enabled in the compiler). From what I understand, MFC overrides the standard operator new, and throws this thing instead. I am fairly certain that this second method is correct in the MFC application itself. MFC overrides new, with its strange CMemoryException throwing version.
The last comes from our base of people who are good with C++, but aren't neccessarily MFC programmers. They are catching const std::bad_alloc&.
What I really don't know is what to expect for static libraries linked into the application. This is were the vast majority of the code that uses bad_alloc lives. Assuming these libraries are not compiled with MFC or ATL, and are written in standard C++ only, can they expect to catch bad_alloc? Or will the presence of MFC in the application they link to infect them with the global new operator and render their attempts to fail cleanly on a bad allocation moot?
If you have an answer, could you explain how this works, or point me to the right reference to sort this out?
It will depend on the compile options for the static libraries to be linked to the application.
If the libraries are compiled with a configuration to use the static Standard C++ run-time then I would expect the operator new from the Standard C++ run-time to be called.
If libraries are compiled with a configuration to use the Standard C++ run-time DLL then the resolution of these functions will be delayed until program load and should be resolved to the MFC replacements of operator new.
I also included a link to this Herb Sutter article regarding handle allocation errors that you may find useful.
Congratulations -- you seem to have stumped all of us. :-)
In theory, if MFC provides an overload for the global new function, then it should be used by all code in the program. But since the static libraries were compiled without knowing about that, I can't say for certain that it would.
The best I can suggest is to write some test code to find out. (I won't have access to my Windows system for the next few hours, or I'd do so myself and give you an answer.)
I've done some MFC-Code-Researches (in VC2010). Here are some facts.
The MFC throws a pointer to a global CMemoryException instance named "_simpleMemoryException" (see also AfxThrowMemoryException())
it is an CException whose m_bAutoDelete is false.
Idea: If it possible to change the c++-only-static-libraries, you can forward declare class CException; and/or class CMemoryException; into the root namespace.
Add a catch-block with catch (CMemoryException* pEx) {...} and/or catch (CException* pEx) {...} at each place where a std::bad_alloc-catch block is. Since the catched pointer is a pointer to a global object, it is not needed to call pEx->Delete();.
In this way the c++-only-static-libraries are not required to include afx.h or/and link against the MFC. I've tried it in VC2010, and it works fine. (only if RTTI is enabled, and only if nobody changes the MFC-NewHandler with AfxSetNewHandler to something else than the default-MFC-NewHandler AfxNewHandler)
You can change the MFC throwing behavior with AfxSetNewHandler(_PNH pfnNewHandler) and provide a pointer to your own NewHandler function. This function should then throw a std::bad_alloc exception.
But now the MFC-program-parts have the problem to catch a std::bad_alloc.