I'm not sure if this is an error or not. The code compiles fine (no warnings), but when I enter a method, a local's value (an NSMutableString) displays this content in the debugger:
__NSAutoreleaseFreedObject(): release of previously deallocated object
I'm not getting an exception, it looks like the contents of the string (which is not even allocated at that time) is that NSAutoReleaseFreedObject warning.
What's going on?
If you don't initialize a normal local variable to anything, its value is undefined — it could be anything. In practice, it will interpret the bit pattern that happens to lie on the stack where the variable is allocated as a value of the variable's type. In this case, the "anything" that the variable contains happens to be the address of that string.
it (likely) means that your app has executed different from usual, and exposed a bug in your ref counting of the object. this type of issue can also be related to improper multithreading.
executing your app to trigger the problem with zombies enabled should help you locate it.
Related
As part of my debugging, I need to dump out a big object. Some of the data shows up like this:
#<Sketchup::Face:0x00007f9119bafea8>
This is the result of calling .inspect on the Sketchup::Face object, and Ruby calls .inspect internally when things are printed to the console.
Is it possible to then get a reference to the actual instance, using that 0x00007f9119bafea8 identifier? I don't even know exactly what this is - a pointer, instance id, something else?
Of course I can always manipulate my data before printing to console but since this is just for temporary debugging I'm hoping there's a quick and easy way.
Note: normally I would put in a binding.pry to avoid this whole business but due to Sketchup's restrictive programming environment it's not possible to use breakpoints there.
I am working on a legacy Ada 95 project inherited from another company. I have recently upgraded our compiler from Gnat 3.13a1 to Gnat 4.7.4. The program still compiles, but one of the tasks is crashing due to a Constraint_Error.
Process_Ua(Buffer, Msg_Kind);
Tr_Log5("MSG KIND IS: " & Message_Received_Type'Image(Msg_Kind));
The Constraint_Error occurs on the second line above, with the message "Invalid Data." Msg_Kind is of type Message_Received_Type (which is an enum type), and it is properly initialised at the start of this subprogram, so I'm having trouble understanding how the data could be invalid, when assigning anything that isn't of Message_Received_Type to Msg_Kind would result in a Constraint_Error when that occurs.
Invalid_Data is always the sign of an uninitialized variable.
I presume you are compiling with -gnatVa and pragma Initialize_Scalars (which you have put in a gnat.adc file or in a file referenced from your project's Builder'Global_Configuration_Pragmas attribute).
In such a case, the compiler tries to initialize the variables with an invalid value (outside of the valid range), and adds additional checks. When the checks fail, they raise the Invalid_Data exception.
Perhaps the older compiler was always initializing an out parameter (but that would be surprising, how would it chose the default value) ?
Maybe asking the question betrays my lack of knowledge about the process, but then again, there's no better reason to ask!
Tracking these down can be frustrating because stack traces can help me know where to start looking but not which object was null.
What is going on under the hood here? Is it because the variable names aren't bundled in the executable?
.NET code built with full optimizations and no debug info: your local variable names are gone, some local variables may have been eliminated entirely.
.NET code built with full optimizations + PDB (or full debug): most local variable names preserved, some local variables may have been eliminated
No optimizations + no debug info: local variable names are gone.
And then we have to consider that whatever you're dealing with may not be in a local variable at all - it might have been the result of a previous function call, on which you're chaining a new function call.
Basically you answered your own question. When you're code is compiled it's transformed in intermediate language (IL). IL does not have variable names the way your code does, arguments to a method being called are pushed on to a stack before the method is called and the currents methods arguments and local variables are referred to by there position. I believe this is because this structure aids the JIT compiler generate code.
The pdb symbols file stores a mapping between the IL generated and your code. It is used to tell you which line in your code each method call in the call stack refers to. Possibly the information stored here isn't detailed enough to say which variable is null, or possibly it was just considered too expensive in terms when of perf to be able to do this. In any case, if you have allowed the compiler to optimize the IL generated there may no longer be a one to one mapping between the variables in the IL and the variables in your code.
Hope that helps,
Rob
There is no "object identifier". There's no way that .NET could say "the object with identifier xxxx is null".
You'll learn how to not make these mistakes, don't worry. Just break down your expressions into smaller pieces, and you'll find which objects you forgot to initialize. You'll learn to iniitialize them in that scenario, and after a while, that case won't happen again.
I want to be able to see the variable values while debugging a release application.
I have set the compiler option as Z7 and given a /DEBUG and /PDB: linker option. Now I have a pdb for the application.
With this set up I am able to put a break point (Windbg) inside the code and it hits properly. But I am not able to see the variable values.
The Locals window only shows the pointer value but I cant see the contents of the same. For instance if I have a pointer to a structure that has an int inside it, it just shows the value of the pointer. If I expand the same by clicking + in the tree, I see the variable name with the value as <Memory access error>
How should I make the release builds show the variable values?
Many times, you cannot see them because they don't exist. If you look at the optimized assembly code, you will find that many intermediate variables are completely removed in favor of performance. That is most likely what you're seeing, and the only way around it is to follow the disassembly and watch the right memory locations / registers.
I've run into an exception and looking at variables in the watch window, I'm seeing some question marks (???). Does this mean it's pointing to an invalid address?
It means that the debugger can't figure out its value.
For example, you see this quite a bit if your code involves HWNDs. If you look through the Windows header files, it's defined like this via a macro:
struct HWND__{int unused;}; typedef struct HWND__ *HWND;
So the type of HWND is really the type "pointer to an HWND__". However, the HWND values you get from functions like CreateWindow() aren't actually pointers to anything.
But the debugger will try to figure out the value of the unused member in the struct, but can't do it:
You will also see these kinds of errors when the watched variable has bad or missing type information.
Is this a C++ style project?
The debugger typically uses the "???" string when it is able to evaluate an expression but is unable to garner any type information for a specific part of the display. This typically occurs because of missing or incorrect PDB symbols.
There is likely a way for this to occur if the expression is accessing corrupted data (overriten virtual tables or RTTI). But I do not 100% know if that is true.
Usually it means the pointer or reference is pointing to inaccessible memory, and thus it cannot get the value to present. For example, if you have a pointer that's supposed to point to a Foo, the debugger will normally interpret the bits that the pointer points to as a Foo--whether the pointer is valid or not. But in some cases, a wild pointer might point to a location that's not even mapped in the process space. In that case, the debugger cannot get the bits.