How to debug macruby? - malloc

I've encountered an inconsistent bug with MacRuby and have no idea how to go about debugging this. If anyone could help would be great.
I don't know if this is due to my own code or is it a bug in the MacRuby framework. I have a feeling it's my own code, something about over-retaining a piece of memory and hence the garbage collection failed.
This is the error from Xcode. Thanks.
CSV Wizard(30245,0x7fff704f7ca0) malloc: resurrection error for object 0x20199da20 while assigning {conservative-block}[196608](0x302360060)[117616] = Array[64](0x20199da20)
garbage pointer stored into reachable memory, break on auto_zone_resurrection_error to debug
CSV Wizard(30245,0x103781000) malloc: garbage block 0x20199da20(Array[64]) was over-retained during finalization, refcount = 1
This could be an unbalanced CFRetain(), or CFRetain() balanced with -release.
Break on auto_zone_resurrection_error() to debug.
CSV Wizard(30245,0x103781000) malloc: fatal resurrection error for garbage block 0x20199da20(Array[64]): over-retained during finalization, refcount = 1

Related

What are the log Error Messages for ClientCheck and InvalidMemPool Error Types of Valgrind

I am running a script in which I am trying to get the all possible Error Valgrind messages in the log file. I have following error messages for corresponding Valgrind Error Types :
Error Types Error message in Log File
1. InvalidFree I free() / delete / delete[] / realloc()
2. MismatchedFree Mismatched free() / delete / delete []
3. InvalidRead Invalid read of size
4. InvalidWrite Invalid write of size
5. InvalidJump Jump to the invalid address
6. Overlap Source and destination overlap in memcpy
7. InvalidMemPool
8. UninitCondition Conditional jump or move depends on uninitialised value
9. UninitValue Use of uninitialised value of size
10. SyscallParam Syscall param execve(filename)
11. ClientCheck
12. Leak_DefinitelyLost definitely lost in loss record
13. Leak_IndirectlyLost Indirectly lost in loss record
14. Leak_StillReachable still reachable in loss record
15. Leak_PossiblyLost Possibly Lost in loss record
I have no idea how to generate error for ClientCheck and InvalidMemPool Error types. Please let me know how to generate it or tell me what is the error message will be generated for these two types of Valgrind Error.
ClientCheck errors are generated following memcheck.h client checks
inserted in your code:client requests VALGRIND_CHECK_MEM_IS_ADDRESSABLE
or VALGRIND_CHECK_MEM_IS_DEFINED will generate such errors if the memory
is not addressable or not defined.
InvalidMemPool errors are generated when the 'POOL' related client requests
in valgrind.h are used incorrectly, typically referencing an incorrect
pool (for example, an already destroyed pool, or a not yet created pool)

Copy Constructor for MyString causes HEAP error. Only Gives Error in Debug Mode

So, I've never experienced this before. Normally when I get an error, it always triggers a breakpoint. However, this time when I build the solution and run it without debugging (ctrl+F5), it gives me no error and runs correctly. But when I try debugging it (F5), it gives me this error:
HEAP[MyString.exe]: HEAP: Free Heap block 294bd8 modified at 294c00 after it was freed
Windows has triggered a breakpoint in MyString.exe.
This may be due to a corruption of the heap, which indicates a bug in MyString.exe or any of the DLLs it has loaded.
This may also be due to the user pressing F12 while MyString.exe has focus.
The output window may have more diagnostic information.
This assignment is due tonight, so I'd appreciate any quick help.
My code is here:
https://gist.github.com/anonymous/8d84b21be6d1f4bc18bf
I've narrowed the problem down in the main to line 18 in main.cpp ( c = a + b; ) The concatenation succeeds, but then when it is to be copied into c, the error message occurs at line 56 in MyString.cpp ( pData = new char[length + 1]; ).
The kicker is I haven't had a problem with this line of code until I tried overloading the operator>>. I've since scrapped that code for the sake of trying to debug this.
Again, any help would be appreciated!
Let's go through line 18:
1. In line 17 you create string c with dynamically allocated memory inside.
2. You make assignment: c = a + b:
2.1. Operator+ creates LOCAL object 'cat'.
2.2. cat's memory is allocated dynamically.
2.3. cat becomes concatenation of two given strings.
2.4. Operator+ exits. cat is LOCAL object and it's being destroyed.
2.4.1. cat is being destroyed. cat's destructor runs.
2.4.2. destructor deletes pData;
2.4.3. After delete you make *pData = NULL. //ERROR - should be pData = NULL (1)
2.5. c is initialized with result of operator+.
2.6. operator= calls copy().
2.7. copy() allocates new memory without checking the current one. //ERROR - memory leak (2)
(1)
pData is char*. In destructor we have: delete[] pData (deletes memory) and then *pData = NULL.
Because pData is a pointer, *pData is same as pData[0]. So you write to already freed memory. This is the cause of your error.
(2)
Additional problem. Copy() overwrites current memory without checking. Should be:
copy()
{
if(this->pData)
{
delete this->pData;
}
//now allocate new buffer and copy
}
Also, when dealing with raw bytes (chars), you don't want to use new() and delete(), but malloc() and free() instead. In this case, in functions like copy(), instead of calling delete() and then new(), you would simply use realloc().
EDIT:
One more thing: errors caused by heap damage usually occur during debugging. In release binary, this will simply overwrite some freed (and maybe already used by someone else) memory. That's why debugging is so important when playing with memory in C++.

Strange memory leak in Visual C++ 2012 Update 2

I don't known why the code below is produce memory leak
XTL::CManagedInternetHandle hRemoteFile;
XTL::CUrlExPtr pFinalUrl;
if (dwServiceType == INTERNET_SERVICE_HTTP)
{
throw CWindowsInternetException(url, E_FAIL, L"Unable to get final URL.");
But, when I move the throw to above, Like this
XTL::CManagedInternetHandle hRemoteFile;
XTL::CUrlExPtr pFinalUrl;
throw CWindowsInternetException(url, E_FAIL, L"Unable to get final URL.");
if (dwServiceType == INTERNET_SERVICE_HTTP)
{
no memory leak occurred.
Solved. The memory leak is occurred in the method caller. I still don't known why memory leak report work only on the first code. It should work on both. Maybe it is a bug of VC++.

debugging a strange error when new is called

I have a program that when run compiled with Microsoft Visual C++ 2008 Express crashes on the line
comparison_vectors = new vec_element[(rbfnetparams->comparison_vector_length)+1];
with the error Unhandled exception at 0x7c93426d in myprog.exe: 0xC0000005: Access violation reading location 0x00000000
rbfnetparams->comparison_vector_length evaluates to 4 (should do and checked in the debugger), and the thing still crashes here when I change the line as a test to:
comparison_vectors = new vec_element[5];
vec_element is a structure with several ints, doubles and a few bools, but no methods or constructor. The thing runs if I replace new with malloc, but then crashes on another new elsewhere. It does not crash every time this line is run, only sometimes, but seems to do so after the same number of iterations of this line each time. Memory usage is only 10MB at this point in the program.
This gets stranger as the same program DOES compile and run under gcc on Solaris, which usually shows up far more errors than Windows does.
Any help would be appreciated, as I am at a loss as to how to debug this one.
Access violation reading location 0x00000000 means "you dereferenced a NULL pointer." It looks like once in a while rbfnetparams is NULL when you reach this line, and thus you get the error.
I can't explain why comparison_vectors = new vec_element[5]; crashes. Is it the same error message?
Check if rbfnetparams is NULL before the line, and see if it gets hit (or add a conditional break point). Then decide if the fact that rbfnetparams is NULL is a symptom of a bigger bug somewhere else.
Dereferencing a NULL pointer is undefined. It's possible that the Solaris compiler does an optimization that masks the bug. That's allowed by the Standard (read the whole series referenced from that post).

Memory leak in Ada.Strings.Unbounded ?

I have a curious memory leak, it seems that the library function to_unbounded_string is leaking!
Code snippets:
procedure Parse (Str : in String;
... do stuff...
declare
New_Element : constant Ada.Strings.Unbounded.Unbounded_String :=
Ada.Strings.Unbounded.To_Unbounded_String (Str); -- this leaks
begin
valgrind output:
==6009== 10,276 bytes in 1 blocks are possibly lost in loss record 153 of 153
==6009== at 0x4025BD3: malloc (vg_replace_malloc.c:236)
==6009== by 0x42703B8: __gnat_malloc (in /usr/lib/libgnat-4.4.so.1)
==6009== by 0x4269480: system__secondary_stack__ss_allocate (in /usr/lib/libgnat-4.4.so.1)
==6009== by 0x414929B: ada__strings__unbounded__to_unbounded_string (in /usr/lib/libgnat-4.4.so.1)
==6009== by 0x80F8AD4: syntax__parser__dash_parser__parseXn (token_parser_g.adb:35)
Where token_parser_g.adb:35 is listed above as the "-- this leaks" line.
Other info: Gnatmake version 4.4.5. gcc version 4.4 valgrind version valgrind-3.6.0.SVN-Debian, valgrind options -v --leak-check=full --read-var-info=yes --show-reachable=no
Any help or insights appreciated,
NWS.
Valgrind clearly says that there is possibly a memory leak. It doesn't necessarily mean there is one. For example, if first call to that function allocates a pool of memory that is re-used during the life time of the program but is never freed, Valgrind will report it as a possible memory leak, even though it is not, as this is a common practice and memory will be returned to OS upon process termination.
Now, if you think that there is a memory leak for real, call this function in a loop, and see it memory continues to grow. If it does - file a bug report or even better, try to find and fix the leak and send a patch along with a bug report.
Hope it helps.
Was trying to keep this to comments, but what I was saying got too long and started to need formatting.
In Ada string objects are generally assumed to be perfectly-sized. The language provies functions to return the size and bounds of any string. Because of this, string handling in Ada is very different than C, and in fact more resembles how you'd do it in a functional language like Lisp.
But the basic principle is that, except in some very unusual situations, if you find yourself using Ada.Strings.Unbounded, you are going about things the wrong way.
The one case where you really can't get around using a variable-length string (or perhaps a buffer with a separate valid_length variable), is when reading strings as input from some external source. As you say, your parsing example is such a situation.
However, even here you should only have that situation on the initial buffer. Your call to your Parse routine should look something like this:
Ada.Text_IO.Get_Line (Buffer, Buffer_Len);
Parse (Buffer(Buffer'first..Buffer'first + Buffer_Len - 1));
Now inside the Parse routine you have a perfectly-sized constant Ada string to work with. If for some reason you need to pull out a subslice, you would do the following:
... --// Code to find start and end indices of my subslice
New_Element : constant String := Str(Element_Start...Element_End);
If you don't actually need to make a copy of that data for some reason though, you are better off just finding Element_Start and Element_End and working with a slice of the original string buffer. Eg:
if Str(Element_Start..Element_End) = "MyToken" then
I know this doesn't answer your question about Ada.Strings.Unbounded possibly leaking. But even if it doesn't leak, that code is relatively wasteful of machine resources (CPU and memory), and probably shouldn't be used for string manipulation unless you really need it.
Are bound[ed] strings scoped?
Expanding on #T.E.D.'s comments, Ada.Strings.Bounded "objects should not be implemented by implicit pointers and dynamic allocation." Instead, the maximum size is fixed when the generic in instantiated. As an implmentation detail, GNAT uses a discriminant to specify the maximum size of the string and a record to store the current size & contents.
In contrast, Ada.Strings.Unbounded requires that "No storage associated with an Unbounded_String object shall be lost upon assignment or scope exit." As an implmentation detail, GNAT uses a buffered implementation derived from Ada.Finalization.Controlled. As a result, the memory used by an Unbounded_String may appear to be a leak until the object is finalized, as for example when the code returns to an enclosing scope.

Resources