Embedded Ruby GC and wrapped structs - c++

I have a win32 console application with ruby 1.9.3 embedded, and I am having problems with ruby GC and objects with wrapped C structs that include a pointer to big data.
After some testing, ruby seems to run the GC when the orphaned objects are taking up some memory. The problem is that ruby does not take into account the memory size the struct pointer is taking up, so it won't start the GC as it thinks that those orphaned objects are too small and do not take up much memory.
I have made an example app that will crash as it creates lots of objects with big data in their wrapped struct, here is the code:
#include <ruby.h>
typedef struct TestClassStructS {
byte* bytes;
} TestClassStruct;
static void testClassFree(TestClassStruct *p) {
delete p->bytes;
delete p;
}
VALUE testClassNew(VALUE klass) {
TestClassStruct* ptr = new TestClassStruct();
ptr->bytes = new byte[1024 * 1024 * 5]();
VALUE obj = Data_Wrap_Struct(klass, NULL, testClassFree, ptr);
rb_obj_call_init(obj, 0, 0);
return obj;
}
VALUE testClassInitialize(VALUE self) {
return self;
}
typedef VALUE (*rubyfunc)(...);
VALUE require_wrap(VALUE arg)
{
return rb_eval_string("GC.enable; loop do; TestClass.new; end");
}
int main(int argc, char** argv[])
{
RUBY_INIT_STACK;
ruby_init();
//freopen("CON", "w", stdout);
ruby_init_loadpath();
ruby_sysinit(&argc, argv);
VALUE testClass = rb_define_class("TestClass", rb_cObject);
rb_define_singleton_method(testClass, "new", (rubyfunc)testClassNew, 0);
rb_define_method(testClass, "initialize", (rubyfunc)testClassInitialize, 0);
int error;
VALUE result = rb_protect(require_wrap, 0, &error);
if (error)
{
VALUE lasterr = rb_gv_get("$!");
VALUE message = rb_obj_as_string(lasterr);
printf(StringValuePtr(message));
}
return ruby_cleanup(0);
}
This is not a real case scenario, but makes me worry that in some cases my app could take too much memory if the GC is not started.
I could fix this problem making regular calls to GC.start, but it seems like a dirty solution for me.
If there was a way for making ruby to prioritize garbage collection when some objects are orphaned or to tell ruby the real size the c struct occupies in memory, would be a nice solution, but I do not know if ruby api includes something like this, I could not find anything like that.

If you can, use xmalloc (from ruby.h I think) to allocate the memory. That is, so far, the only way to make sure that the allocated memory gets accounted for the next GC trigger.
There is a new dsize function registered with wrapped C structs, but it seems that it is not (yet ?) used in ruby 1.9.3

Related

Proper memory control in gSoap

I'm currently developing application using gSoap library and has some misunderstanding of proper usage library. I has generated proxy object (-j flag) which wrapped my own classes, as you can see below. Application must work 24/7 and connect simultaneously to many cameras (~50 cameras), so after every request i need to clear all temporary data. Is it normal usage to call soap_destroy() and soap_end() after every request? Because it seem's overkill to do it after each request. May be exists another option of proper usage?
DeviceBindingProxy::destroy()
{
soap_destroy(this->soap);
soap_end(this->soap);
}
class OnvifDeviceService : public Domain::IDeviceService
{
public:
OnvifDeviceService()
: m_deviceProxy(new DeviceBindingProxy)
{
soap_register_plugin(m_deviceProxy->soap, soap_wsse);
}
int OnvifDeviceService::getDeviceInformation(const Access::Domain::Endpoint &endpoint, Domain::DeviceInformation *information)
{
_tds__GetDeviceInformation tds__GetDeviceInformation;
_tds__GetDeviceInformationResponse tds__GetDeviceInformationResponse;
setupUserPasswordToProxy(endpoint);
m_deviceProxy->soap_endpoint = endpoint.endpoint().c_str();
int result = m_deviceProxy->GetDeviceInformation(&tds__GetDeviceInformation, tds__GetDeviceInformationResponse);
m_deviceProxy->soap_endpoint = NULL;
if (result != SOAP_OK) {
Common::Infrastructure::printSoapError("Fail to get device information.", m_deviceProxy->soap);
m_deviceProxy->destroy();
return -1;
}
*information = Domain::DeviceInformation(tds__GetDeviceInformationResponse.Manufacturer,
tds__GetDeviceInformationResponse.Model,
tds__GetDeviceInformationResponse.FirmwareVersion);
m_deviceProxy->destroy();
return 0;
}
}
To ensure proper allocation and deallocation of managed data:
soap_destroy(soap);
soap_end(soap);
You want to do this often to avoid memory to fill up with old data. These calls remove all deserialized data and data you allocated with the soap_new_X() and soap_malloc() functions.
All managed allocations are deleted with soap_destroy() followed by soap_end(). After that, you can start allocating again and delete again, etc.
To allocate managed data:
SomeClass *obj = soap_new_SomeClass(soap);
You can use soap_malloc for raw managed allocation, or to allocate an array of pointers, or a C string:
const char *s = soap_malloc(soap, 100);
Remember that malloc is not safe in C++. Better is to allocate std::string with:
std::string *s = soap_new_std__string(soap);
Arrays can be allocated with the second parameter, e.g. an array of 10 strings:
std::string *s = soap_new_std__string(soap, 10);
If you want to preserve data that otherwise gets deleted with these calls, use:
soap_unlink(soap, obj);
Now obj can be removed later with delete obj. But be aware that all pointer members in obj that point to managed data have become invalid after soap_destroy() and soap_end(). So you may have to invoke soap_unlink() on these members or risk dangling pointers.
A new cool feature of gSOAP is to generate deep copy and delete function for any data structures automatically, which saves a HUGE amount of coding time:
SomeClass *otherobj = soap_dup_SomeClass(NULL, obj);
This duplicates obj to unmanaged heap space. This is a deep copy that checks for cycles in the object graph and removes such cycles to avoid deletion issues. You can also duplicate the whole (cyclic) managed object to another context by using soap instead of NULL for the first argument of soap_dup_SomeClass.
To deep delete:
soap_del_SomeClass(obj);
This deletes obj but also the data pointed to by its members, and so on.
To use the soap_dup_X and soap_del_X functions use soapcpp2 with options -Ec and -Ed, respectively.
In principle, static and stack-allocated data can be serialized just as well. But consider using the managed heap instead.
See https://www.genivia.com/doc/databinding/html/index.html#memory2 for more details and examples.
Hope this helps.
The way memory has to be handled is described in Section 9.3 of the GSoap documentation.

Native node.js addon error pointer being freed was not allocated

I'm writing a function that looks like this:
Nan::MaybeLocal<v8::Object> getIconForFile(const char * str) {
NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFile:[NSString stringWithUTF8String:str]];
NSData * tiffData = [icon TIFFRepresentation];
unsigned int length = [tiffData length];
//TODO this is causing `malloc: *** error for object 0x10a202000: pointer being freed was not allocated`
char * iconBuff = (char *)[tiffData bytes];
Nan::MaybeLocal<v8::Object> ret = Nan::NewBuffer(iconBuff, length);
return ret;
}
It works as expected except when it gets run by node.js, it throws malloc: *** error for object 0x10a202000: pointer being freed was not allocated. I've tried different things using malloc, etc but nothing is working. I understand that Nan::NewBuffer is trying to free the buffer data somehow and that's where the problem is coming from. Maybe the iconBuff variable is allocated to the stack and when it goes out of scope and Nan::NewBuffer tries to free it, it's freeing a null pointer? I'm not sure and I'm sort of lost :(
Here's the code that "fixed" it but #uliwitness pointed out in his answer that it still has memory management problems:
Nan::MaybeLocal<v8::Object> getIconForFile(const char * str) {
NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFile:[NSString stringWithUTF8String:str]];
NSData * tiffData = [icon TIFFRepresentation];
unsigned int length = [tiffData length];
char * iconBuff = new char[length];
[tiffData getBytes:iconBuff length:length];
Nan::MaybeLocal<v8::Object> ret = Nan::NewBuffer(iconBuff, length);
return ret;
}
Here's the specific code I ended up going with based on #uliwitness' answer:
Nan::MaybeLocal<v8::Object> getIconForFile(const char * str) {
#autoreleasepool {
NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFile:[NSString stringWithUTF8String:str]];
NSData * tiffData = [icon TIFFRepresentation];
unsigned int length = [tiffData length];
return Nan::CopyBuffer((char *) [tiffData bytes], length);
}
}
This seems to be the most elegant solution and from some quick and dirty testing, seems to result in a smaller resident set size in node.js over many invocations, for whatever that's worth.
I googled for documentation about Nan::NewBuffer, and found this page: https://git.silpion.de/users/baum/repos/knoesel-mqttdocker-environment/browse/devicemock/node_modules/nan/doc/buffers.md
This says:
Note that when creating a Buffer using Nan::NewBuffer() and an
existing char*, it is assumed that the ownership of the pointer is
being transferred to the new Buffer for management. When a
node::Buffer instance is garbage collected and a FreeCallback has not
been specified, data will be disposed of via a call to free(). You
must not free the memory space manually once you have created a Buffer
in this way.
So the code in your own answer is incorrect, because a buffer created using new char[] needs to be disposed of using delete [] (this is different from delete, FWIW), however you're giving it to a function that promises to call free on it. You're just accidentally turning off the error message, not fixing the error.
So at the least, you should use malloc instead of new there.
This page also mentions another function, Nan::CopyBuffer(), which it describes as:
Similar to Nan::NewBuffer() except that an implicit memcpy will occur
within Node. Calls node::Buffer::Copy(). Management of the char* is
left to the user, you should manually free the memory space if
necessary as the new Buffer will have its own copy.
That sounds like a better choice for your original code. You can pass it the NSData's bytes and it will even do the copying for you. You don't have to worry about "manually freeing the memory space", as the memory is owned by the NSData, which will take care of disposing of it when it is released (If you're using ARC, ARC will release the NSData, if you're not ARC, you should add an #autoreleasepool so it gets released).
PS - At the bottom of that page, it also mentions that you could use a Nan::FreeCallback and pass it to Nan::NewBuffer. If you provide one there that calls delete [] on the buffer it is given, the code from your answer would work as well. But really, why write additional code for something Nan::CopyBuffer will apparently already do for you?

How do I clean everything in lua stack from C++?

Although I fixed the bug by call as less time lua_getglobal as I can, it's not good enough for long term. So does anyone know how do I clean everything in lua's stack to prevent memory management problems?
---EDIT---
From the experiments i just did, lua_settop will clean up the table to the given value. However, in the time i know how many items are there i want to remove, is lua_pop more efficient?
A simple lua_settop(L, 0); should do the trick.
A simple, albeit contrive, example say you have a lua_CFunction:
int foo(lua_State *L)
{
// marshal some random data
int bar = luaL_checknumber(L, 1);
const char *baz = luaL_checkstring(L, 2);
// do foo's task
// completely clear the stack before return
lua_settop(L, 0);
return 0;
}
This is contrived because if foo is called by the VM then cleanup is not necessary. But if you have C++ code calling foo directly this may be necessary. At any rate hopefully this illustrates its calling context.

Serial allocators/deallocators

I have a code that has a large number of mallocs and device-specific API mallocs (I'm programming on a GPU, so cudaMalloc).
Basically my end of my beginning of my code is a big smorgasbord of allocation calls, while my closing section is deallocation calls.
As I've encapsulated my global data in structures, the deallocations are quite long, but at least I can break them into a separate function. On the other hand, I would like a shorter solution. Additionally an automatic deallocator would reduce the risk of memory leaks created if I forget to explicitly write the deallocation in the global allocator function.
I was wondering whether it'd be possible to write some sort of templated class wrapper that can allow me to "register" variables during the malloc/cudaMalloc process, and then at the end of simulation do a mass loop-based deallocation (deregistration). To be clear I don't want to type out individual deallocations (free/cudaFrees), because again this is long and undesirable, and the assumption would be that anything I register won't be deallocated until the device simulation is complete and main is terminating.
A benefit here is that if I register a new simulation duration variable, it will automatically deallocate, so there's no danger of me forgetting do deallocate it and creating a memory leak.
Is such a wrapper possible?
Would you suggest doing it?
If so, how?
Thanks in advance!
An idea:
Create both functions, one that allocates memory and provides valid pointers after register them in a "list" of allocated pointers. In the second method, loop this list and deallocate all pointers:
// ask for new allocated pointer that will be registered automatically in list of pointers.
pointer1 = allocatePointer(size, listOfPointers);
pointer2 = allocatePointer(size, listOfPointers);
...
// deallocate all pointers
deallocatePointers(listOfPointers);
Even, you may use different listOfPointers depending of your simulation scope:
listOfPointer1 = getNewListOfPointers();
listOfPointer2 = getNewListOfPointers();
....
p1 = allocatePointer(size, listOfPointer1);
p2 = allocatePointer(size, listOfPointer2);
...
deallocatePointers(listOfPointers1);
...
deallocatePointers(listOfPointers2);
There are many ways to skin a cat, as they say.
I would recommend thrust's device_vector as a memory management tool. It abstracts allocation, deallocation, and memcpy in CUDA. It also gives you access to all the algorithms that Thrust provides.
I wouldn't recommend keeping random lists of unrelated pointers as Tio Pepe recommends. Instead you should encapsulate related data into a class. Even if you use thrust::device_vector you may want to encapsulate multiple related vectors and operations on them into a class.
The best choice is probably to use the smart pointers from C++ boost library, if that is an option.
If not, the best you can hope for in C is a program design that allows you to write allocation and deallocation in one place. Perhaps something like the following pseudo code:
while(!terminate_program)
{
switch(state_machine)
{
case STATE_PREOPERATIONAL:
myclass_init(); // only necessary for non-global/static objects
myclass_mem_manager();
state_machine = STATE_RUNNING;
break;
case STATE_RUNNING:
myclass_do_stuff();
...
break;
...
case STATE_EXIT:
myclass_mem_manager();
terminate_program = true;
break;
}
void myclass_init()
{
ptr_x = NULL;
ptr_y = NULL;
/* Where ptr_x, ptr_y are some of the many objects to allocate/deallocate.
If ptr is a global/static, (static storage duration) it is
already set to NULL automatically and this function isn't
necessary */
}
void myclass_mem_manager()
{
ptr_x = mem_manage (ptr_x, items_x*sizeof(Type_x));
ptr_y = mem_manage (ptr_y, items_y*sizeof(Type_y));
}
static void* mem_manage (const void* ptr, size_t bytes_n)
{
if(ptr == NULL)
{
ptr = malloc(bytes_n);
if (ptr == NULL)
{} // error handling
}
else
{
free(ptr);
ptr = NULL;
}
return ptr;
}

Is it possible to *safely* return a TCHAR* from a function?

I've created a function that will convert all the event notification codes to strings. Pretty simple stuff really.
I've got a bunch of consts like
const _bstr_t DIRECTSHOW_MSG_EC_ACTIVATE("A video window is being activated or deactivated.");
const _bstr_t DIRECTSHOW_MSG_EC_BUFFERING_DATA("The graph is buffering data, or has stopped buffering data.");
const _bstr_t DIRECTSHOW_MSG_EC_BUILT("Send by the Video Control when a graph has been built. Not forwarded to applications.");
.... etc....
and my function
TCHAR* GetDirectShowMessageDisplayText( int messageNumber )
{
switch( messageNumber )
{
case EC_ACTIVATE: return DIRECTSHOW_MSG_EC_ACTIVATE;
case EC_BUFFERING_DATA: return DIRECTSHOW_MSG_EC_BUFFERING_DATA;
case EC_BUILT: return DIRECTSHOW_MSG_EC_BUILT;
... etc ...
No big deal. Took me 5 minutes to throw together.
... but I simply don't trust that I've got all the possible values, so I want to have a default to return something like "Unexpected notification code (7410)" if no matches are found.
Unfortunately, I can't think of anyway to return a valid pointer, without forcing the caller to delete the string's memory ... which is not only nasty, but also conflicts with the simplicity of the other return values.
So I can't think of any way to do this without changing the return value to a parameter where the user passes in a buffer and a string length. Which would make my function look like
BOOL GetDirectShowMessageDisplayText( int messageNumber, TCHAR* outBuffer, int bufferLength )
{
... etc ...
I really don't want to do that. There must be a better way.
Is there?
I'm coming back to C++ after a 10 year hiatus, so if it's something obvious, don't discount that I've overlooked it for a reason.
C++? std::string. It's not going to destroy the performance on any modern computer.
However if you have some need to over-optimize this, you have three options:
Go with the buffer your example has.
Have the users delete the string afterwards. Many APIs like this provide their own delete function for deleting each kind of dynamically allocated return data.
Return a pointer to a static buffer which you fill in with the return string on each call. This does have some drawbacks, though, in that it's not thread safe, and it can be confusing because the returned pointer's value will change the next time someone calls the function. If non-thread-safety is acceptable and you document the limitations, it should be all right though.
If you are returning a point to a string constant, the caller will not have to delete the string - they'll only have to if you are new-ing the memory used by the string every time. If you're just returning a pointer to a string entry in a table of error messages, I would change the return type to TCHAR const * const and you should be OK.
Of course this will not prevent users of your code to attempt to delete the memory referenced by the pointer but there is only so much you can do to prevent abuse.
Just declare use a static string as a default result:
TCHAR* GetDirectShowMessageDisplayText( int messageNumber )
{
switch( messageNumber )
{
// ...
default:
static TCHAR[] default_value = "This is a default result...";
return default_value;
}
}
You may also declare "default_value" outside of the function.
UPDATE:
If you want to insert a message number in that string then it won't be thread-safe (if you are using multiple threads). However, the solution for that problem is to use thread-specific string. Here is an example using Boost.Thread:
#include <cstdio>
#include <boost/thread/tss.hpp>
#define TCHAR char // This is just because I don't have TCHAR...
static void errorMessageCleanup (TCHAR *msg)
{
delete []msg;
}
static boost::thread_specific_ptr<TCHAR> errorMsg (errorMessageCleanup);
static TCHAR *
formatErrorMessage (int number)
{
static const size_t MSG_MAX_SIZE = 256;
if (errorMsg.get () == NULL)
errorMsg.reset (new TCHAR [MSG_MAX_SIZE]);
snprintf (errorMsg.get (), MSG_MAX_SIZE, "Unexpected notification code (%d)", number);
return errorMsg.get ();
}
int
main ()
{
printf ("Message: %s\n", formatErrorMessage (1));
}
The only limitation of this solution is that returned string cannot be passed by the client to the other thread.
Perhaps have a static string buffer you return a pointer to:
std::ostringstream ss;
ss << "Unexpected notification code (" << messageNumber << ")";
static string temp = ss.str(); // static string always has a buffer
return temp.c_str(); // return pointer to buffer
This is not thread safe, and if you persistently hold the returned pointer and call it twice with different messageNumbers, they all point to the same buffer in temp - so both pointers now point to the same message. The solution? Return a std::string from the function - that's modern C++ style, try to avoid C style pointers and buffers. (It looks like you might want to invent a tstring which would be std::string in ANSI and std::wstring in unicode, although I'd recommend just going unicode-only... do you really have any reason to support non-unicode builds?)
You return some sort of self-releasing smart pointer or your own custom string class. You should follow the interface as it's defined in std::string for easiest use.
class bstr_string {
_bstr_t contents;
public:
bool operator==(const bstr_string& eq);
...
~bstr_string() {
// free _bstr_t
}
};
In C++, you never deal with raw pointers unless you have an important reason, you always use self-managing classes. Usually, Microsoft use raw pointers because they want their interfaces to be C-compatible, but if you don't care, then don't use raw pointers.
The simple solution does seem to be to just return a std::string. It does imply one dynamic memory allocation, but you'd probably get that in any case (as either the user or your function would have to make the allocation explicitly)
An alternative might be to allow the user to pass in an output iterator which you write the string into. Then the user is given complete control over how and when to allocate and store the string.
On the first go-round I missed that this was a C++ question rather than a plain C question. Having C++ to hand opens up another possibility: a self-managing pointer class that can be told whether or not to delete.
class MsgText : public boost::noncopyable
{
const char* msg;
bool shouldDelete;
public:
MsgText(const char *msg, bool shouldDelete = false)
: msg(msg), shouldDelete(shouldDelete)
{}
~MsgText()
{
if (shouldDelete)
free(msg);
}
operator const char*() const
{
return msg;
}
};
const MsgText GetDirectShowMessageDisplayText(int messageNumber)
{
switch(messageNumber)
{
case EC_ACTIVATE:
return MsgText("A video window is being activated or deactivated.");
// etc
default: {
char *msg = asprintf("Undocumented message (%u)", messageNumber);
return MsgText(msg, true);
}
}
}
(I don't remember if Windows CRT has asprintf, but it's easy enough to rewrite the above on top of std::string if it doesn't.)
Note the use of boost::noncopyable, though - if you copy this kind of object you risk double frees. Unfortunately, that may cause problems with returning it from your message-pretty-printer function. I'm not sure what the right way to deal with that is, I'm not actually much of a C++ guru.
You already use _bstr_t, so if you can just return those directly:
_bstr_t GetDirectShowMessageDisplayText(int messageNumber);
If you need to build a different message at runtime you can pack it into a _bstr_t too. Now the ownership is clear and the use is still simple thanks to RAII.
The overhead is negligible (_bstr_t uses ref-counting) and the calling code can still use _bstr_ts conversion to wchar_t* and char* if needed.
There's no good answer here, but this kludge might suffice.
const char *GetDirectShowMessageDisplayText(int messageNumber)
{
switch(messageNumber)
{
// ...
default: {
static char defaultMessage[] = "Unexpected notification code #4294967296";
char *pos = defaultMessage + sizeof "Unexpected notification code #" - 1;
snprintf(pos, sizeof "4294967296" - 1, "%u", messageNumber);
return defaultMessage;
}
}
}
If you do this, callers must be aware that the string they get back from GetDirectShowMessageText might be clobbered by a subsequent call to the function. And it's not thread safe, obviously. But those might be acceptable limitations for your application.