Garbage value undetected in debug mode - objective-c

I've recently discovered the following in my code:
for (NSInteger i; i<x; i++){
...
}
Now, clearly, i should have been initialised. What I find strange is that while in "debug" profile (XCode), this error goes undetected and the for loop executes without issue. When the application is released using the "release" profile, a crash occurs.
What flags are responsible for letting this kind of mistake execute in "debug" profile?
Thanks in advance.

This could be considered a Heisenbug. A declaration without an initialization will typically allocate some space in the stack frame for the variable and if you read the variable you will get whatever happened to be at that location in memory. When compiled for the debug profile the storage for variables can shift around compared to release. It just happens that whatever is in that location in memory for debug mode does not cause a crash (probably a positive number) but when in release mode it is some value that causes a crash (probably a negative number).

The clang static analyser should detect this. I have the analyse when building option switched on always.

In the C language, using an initialized variable isn't an error but an Undefined Behavior.
Undefined behavior exists because C is designed to be a very efficient low-level language. Using an initialized variable is undefined behavior because it allows the compiler to optimize the variable allocation, as no default value is required.
But the compiler is licensed to do whatever he wants when an undefined behavior occurs. The C Standard FAQ says:
Anything at all can happen; the Standard imposes no requirements. The program may fail to compile, or it may execute incorrectly (either crashing or silently generating incorrect results), or it may fortuitously do exactly what the programmer intended.
So any implementation of an undefined behavior is valid (even if it produces code that formats your hard drive).
Xcode uses different optizations for Debug and Release configurations. Debug configuration has no optimization (-O0 flag) so the compiled executable must stays close to your code, allowing you to debug it more easily. On the other hand, Release configuration produces strongly optimized executables (-Os flag) because you want your application to run fast.
Due to that difference, undefined behaviours may (or may not) produce different results in Release and Debug configurations.
Though the LLVM compiler is quite verbose, it does not emit warnings by default for undefined behaviors. You may however run the static analyzer, which can detect that kind of issues.
More information about undefined behaviors and how they are handled by compilers in What Every Programmer Should Know About Undefined Behavior.

I doubt it is so much flags as the compiler is optimizing out the "unused" variable i. Release mode includes far more optimizations then debug mode.

Different compiler optimizations may or may not use a different memory location or register for you uninitialized variable. Different garbage (perhaps from previously used variables, computations or addresses used by your app) will be left in these different locations before you start using the variable.
The "responsibility" goes to not initializing the variable, as what garbage is left in what locations may not be visible to the compiler, especially in debug mode with most optimatizations off (e.g. you got "lucky" with the debug build).

i has not been initialized . You are just declaring the i variable not initializing the variable.
Writing just NSInteger i; just declares a variable not initializes it.
You can initialize the variable by below mentioned code.
for (NSInteger i=1; i<x; i++){
...
}

Related

malloc() always returns NULL in ChibiOS

I have a ChibiOS application where I'm using dynamic memory allocation via malloc().
However, I observed that 100% of the time I call malloc(), it returns NULL. I have confirmed that:
The microcontroller memory is not full
The error also occurs for size-1 malloc calls, so the memory chunk size is not the cause of the issues.
errno is always ENOMEM after the malloc() call
How can I resolve this issue?
When you look at the definition of _sbrk in os/various/syscalls.c, you can clearly see that it always returns a ENOMEM error if CH_CFG_USE_MEMCORE == FALSE.
Unless you set CH_CFG_USE_MEMCORE = TRUE in chconf.h, the ChibiOS core memory manager is disabled completely and _sbrk and other memory-related functions are only included in the object files so no linking errors occur.
In order to properly configure ChibiOS correctly, ensure that the following is set in chconf.h:
#define CH_CFG_USE_MEMCORE TRUE
In order to avoid running into reliability issues, you might want to use memory pools or alternative algorithms instead where possible. See this detailed explanation for a description why malloc() is often a bad idea on embedded systems (it's actually forbidden in most embedded coding standards entirely).

Objective-C ARC and longjmp

What is the best practice for mixing Objective-C ARC with longjmp?
I am using Lua as scripting language, and my platform exports custom library for scripts. Entry points do check arguments with luaL_checkinteger(L, 2) (among others), which, in turn, may call luaL_typerror(L, 2, ...), that is implemented in Lua with setjmp/longjmp. As far as I know, ARC simply auto-generates retain/release code, but what happens if it longjmps out of scope? Will this code leak on mistyped arguments?
static int
set_tag(lua_State *L)
{
NSControl *control = (__bridge NSControl *)lua_topointer(L, 1);
[control setTag:(NSInteger)luaL_checkinteger(L, 2)]; // may longjmp!
return 0;
}
In the snippet above, control will be temporarily retained by ARC, but with longjmps uncatchable nature, corresponding release call may never happen. On the other hand, all arguments may be checked before assigning to control variable.
static int
set_tag(lua_State *L)
{
NSInteger tag = luaL_checkinteger(L, 2); // may longjmp!
NSControl *control = (__bridge NSControl *)lua_topointer(L, 1);
[control setTag:tag];
return 0;
}
Does it resolve [potential] leak above? Are there better ways to do this?
UPDATE: longjmp only unwinds to Lua internals, and never crosses any system code, except for Lua source (which is aware), and my entry points (which I hope are aware).
I'm pretty sure that second snippet does right, but I need kind of formal proof.
LATE UPDATE:
LuaJIT implements dwarf2-compatible errors, so they are just like C++ exceptions. Pass -fobjc-arc-exceptions compiler flag to arc-enabled sources with Lua code and any retained object will be released on any lua_error. Nothing to worry about now! You are still not allowed to throw errors across Cocoa runtime, though.
I recall that original Lua may be compiled with exceptions too, but I'm not sure.
Doesn't really matter if ARC is in use or not; any setjmp/longjmp that jumps over any frame of code from the system frameworks will yield undefined behavior (for the same reason that exceptions cannot be used for recoverable error handling).
So, yes, that code might leak. Might because it depends on whether the compiler emits a retain/release in that block and where. Might also because whether the compiler emits retain/release will be impacted by the optimization level and, over time, the version of the compiler.
longjmp only unwinds to Lua internals, and never crosses any system
code, except for Lua source (which is aware), and my entry points
(which I hope are aware).
That is helpful. As long as you structure your entry points such that they never intermingle system scope with Lua jumpable scopes, you should be OK. I would recommend turning off ARC in the source files where you have to manage this (and, of course, put the ObjC->Lua interface into a nicely encapsulated bit of implementation so the rest of your code can be ARC clean).
Consider, though, that there is non-obvious risk:
for(id x in anArray) {
... lua call that causes longjmp ...
}
The above would cause lua to "jump over" system code. Same goes for enumerateWithBlock:, KVO, Notification handlers, etc...
You're going to have to think very very carefully about every potential stack trigger by a call from Lua into your code. If that call triggers any kind of automated behavior on the part of the system that could then call Lua API that could trigger a longjmp, all bets are off.
longjmp() may cause crashes or leaks in ARC. Arranging the code so longjmp() and ARC don't interfere is difficult.
If the longjmp() is only for a fatal error path and you expect to halt the process in response then you may be able to ignore the problem. This is what ARC does with C++/ObjC exceptions by default. ARC code is expected to leak when exceptions are thrown. There's a compiler option to enable the clean up code for exceptions, but that hurts performance.
If the longjmp() is not a process-killing error then your best option is to turn off ARC in any code that may be skipped by a longjmp() call.

Valgrind not showing source code for the dynamic library

I'm trying to debug my program using Valgrind. I compiled with -g3 -O0 -ggdb. How ever I am unable to see the source code corresponding to the point where Valgrind finds problem. The output just shows the name of the (binary)library.
These addresses are of no interest. They belong to the runtime support code that runs after main and calls destructors of global objects and atexit routines. They do not have any source (that you wrote) associated with them.
You can tell that from their placement between exit and __cxa_finalize in the call stack. No user code could possibly belong there.
Silly question, but do you have the source for that library? If not, and that library wasn't compiled with debugging symbols, valgrind isn't going to decompile the binary and show you source.
Valgrind is complaining about a double free on exit. The line:
Address 0x5980ec0 is 0 bytes inside a block of size 29 free'd
Is pointing you where this memory block was previously freed. Taking into account that this is also in exit I can think of two possible reasons:
Some global and static variables that are been freed (with C++ I've seen this problem when directly assigning two global objects, containing pointers, using default copy constructor. As both pointers refer to same memory address, on exit, this is freed twice).
libslm.so has been loaded by using dlopen, then, on exit, it is closed and can also cause some problems with currently managed memory.
I'm assuming that libslm.so is yours so, I think, in both scenarios is important to know something about lines you marked. Have you checked that the path in the log is the same were you have your libraries with debug information? Is AddrScram linked against these libraries (with same exact path)?

Local variable being stored over different function calls. weird

I'm bewildered by whats happening. It's more of a trick question I don't know the answer to.
I have the following function inside my main.m of an Objective-C program.
int incrementCounter(){
int counter;
counter+=2;
return counter;
}
and inside my main.m
NSLog(#"Counter: %d",incrementCounter());
NSLog(#"Counter: %d",incrementCounter());
NSLog(#"Counter: %d",incrementCounter());
The weird thing is one mac book(don't know the Xcode version ) when I executed this the output was:
2013-05-28 19:16:27.131 SOQ[4923:707] Counter: 1
2013-05-28 19:16:27.132 SOQ[4923:707] Counter: 3
2013-05-28 19:16:27.132 SOQ[4923:707] Counter: 5
My questions here:
1. How did counter get initialized to 1? (when i use static it get initialized to zero)
2. How is the value being stored over successive method calls?
3. When I check for the memory location of this variable for different executions of the program it remains the same. How does that happen?
And when I executed the same piece of code in another mac(lion Xcode 4.2.1) it gives the following output:
2013-05-28 19:16:27.131 SOQ[4923:707] Counter: 32769
2013-05-28 19:16:27.132 SOQ[4923:707] Counter: 32769
2013-05-28 19:16:27.132 SOQ[4923:707] Counter: 32769
My questions here:
1. How does this behavior change from mac to mac? //I was thinking different compiler versions but it was both using the same(not sure though) . Is there any other way?
2. How did the counter get initialized to 32767? I was thinking garbage value, but isn't the objective-c compiler supposed to initialize primitive like int to zero? And I'm getting the same 32769 over and over again. How?
Maybe I'm missing out on something basic. Any pointers?
How did counter get initialized to 1? (when i use static it get initialized to zero)
How is the value being stored over successive method calls?
When I check for the memory location of this variable for different executions of the program it remains the same. How does that happen?
How does this behavior change from mac to mac? //I was thinking different compiler versions but it was both using the same(not sure though) . Is there any other way? 
How did the counter get initialized to 32767? I was thinking garbage value, but isn't the objective-c compiler supposed to initialize primitive like int to zero? And I'm getting the same 32769 over and over again. How?
The answer to all these questions is: coincidence. You are using an uninitialized value. You can't rely on this value, and you should not use it at all. The compiler probably warns you about it too.
The compiler does not initalize local variables of primitive types. If you use ARC local objects are initialized to nil automatically, but not primitive types.
Primitive instance variables are initialized to 0 and instance variables pointing to objects are initialized to nil.
In your incrementCounter function you are using counter which is an uninitialised variable, so the behaviour is 'undefined' - which means what you're seeing is perfectly valid behaviour (in that any behaviour would be valid since the behaviour is undefined).
So as for what is actually happening (or could potentially be happening, depending on the compiler and runtime implementations):
1-1: It's undefined what the initial value will be, but it might end up always being the same for multiple executions if the object loader behaves in a deterministic way and just happens to leave a certain bit-pattern in that memory prior to beginning execution of your program, or even just by accident.
1-2: When incrementCounter is called some memory on the stack is allocated (the next available chunk, on the top of the stack), then incrementCounter increments and returns it. Then NSLog is called, using the same stack-memory (but perhaps a different size). NSLog happens to not trample on that value (probably because the compiler puts it in a place used for return values and NSLog doesn't have a return value). Then incrementCounter is called again, the same stack-memory is re-used and the value just happens to not have been trampled. Try implementing a second otherIncrementCounter method in exactly the same way to see if they are both sharing the same memory for that return value, also take a look at &counter in both methods, it's probably the same.
1-3: The local address-space that your program uses when it is run as a process is local to that process. A different program writing to the same address won't trample your process's memory. A kernel implementation can map this memory however it likes, for example it could use the same starting-point for the stack address space for all its processes.
2-1 & 2-2: See 1-1 and 1-2 above. Perhaps a different build of the kernel, object loader, OS, etc. In this case perhaps NSLog is doing something with that value, perhaps using it temporarily, to set it to 32767 each time. The implementation of NSLog may have changed or may just be compiled with a different compiler version on that machine - it's in a shared library that's loaded and linked at run-time, not compiled into your executable.
In general it's fairly pointless to wonder about these things, there are too many reasons that things could be working as they are, but it's useful to know how compilers and stacks work so I hope my answers above give you inspiration to learn about that a bit more. However, when programming (and not learning about compilers) simply don't rely on undefined behaviour, turn on lots of warnings and treat them as errors so you don't ever accidentally depend on the implementations of compilers, runtimes, or library implementations.

Avoiding, finding and removing memory leaks in Cocoa

Memory (and resource) leaks happen. How do you make sure they don't?
What tips & techniques would you suggest to help avoid creating memory leaks in first place?
Once you have an application that is leaking how do you track down the source of leaks?
(Oh and please avoid the "just use GC" answer. Until the iPhone supports GC this isn't a valid answer, and even then - it is possible to leak resources and memory on GC)
In XCode 4.5, use the built in Static Analyzer.
In versions of XCode prior to 3.3, you might have to download the static analyzer. These links show you how:
Use the LLVM/Clang Static Analyzer
To avoid creating memory leaks in the first place, use the Clang Static Analyzer to -- unsurprisingly -- analyse your C and Objective-C code (no C++ yet) on Mac OS X 10.5. It's trivial to install and use:
Download the latest version from this page.
From the command-line, cd to your project directory.
Execute scan-build -k -V xcodebuild.
(There are some additional constraints etc., in particular you should analyze a project in its "Debug" configuration -- see http://clang.llvm.org/StaticAnalysisUsage.html for details -- the but that's more-or-less what it boils down to.)
The analyser then produces a set of web pages for you that shows likely memory management and other basic problems that the compiler is unable to detect.
If your project does not target Mac OS X desktop, there are a couple of other details:
Set the Base SDK for All Configurations to an SDK that uses the Mac OS X desktop frameworks...
Set the Command Line Build to use the Debug configuration.
(This is largely the same answer as to this question.)
Don't overthink memory management
For some reason, many developers (especially early on) make memory management more difficult for themselves than it ever need be, frequently by overthinking the problem or imagining it to be more complicated than it is.
The fundamental rules are very simple. You should concentrate just on following those. Don't worry about what other objects might do, or what the retain count is of your object. Trust that everyone else is abiding by the same contract and it will all Just Work.
In particular, I'll reiterate the point about not worrying about the retain count of your objects. The retain count itself may be misleading for various reasons. If you find yourself logging the retain count of an object, you're almost certainly heading down the wrong path. Step back and ask yourself, are you following the fundamental rules?
Always use accessor methods; declare accessors using properties
You make life much simpler for yourself if you always use accessor methods to assign values to instance variables (except in init* and dealloc methods). Apart from ensuring that any side-effects (such as KVO change notifications) are properly triggered, it makes it much less likely that you'll suffer a copy-and-paste or some other logic error than if you sprinkle your code with retains and releases.
When declaring accessors, you should always use the Objective-C 2 properties feature. The property declarations make the memory management semantics of the accessors explicit. They also provide an easy way for you to cross-check with your dealloc method to make sure that you have released all the properties you declared as retain or copy.
The Instruments Leaks tool is pretty good at finding a certain class of memory leak. Just use "Start with Performance Tool" / "Leaks" menu item to automatically run your application through this tool. Works for Mac OS X and iPhone (simulator or device).
The Leaks tool helps you find sources of leaks, but doesn't help so much tracking down the where the leaked memory is being retained.
Follow the rules for retaining and releasing (or use Garbage Collection). They're summarized here.
Use Instruments to track down leaks. You can run an application under Instruments by using Build > Start With Performance Tool in Xcode.
I remember using a tool by Omni a while back when I was trying to track down some memory leaks that would show all retain/release/autorelease calls on an object. I think it showed stack traces for the allocation as well as all retains and releases on the object.
http://www.omnigroup.com/developer/omniobjectmeter/
First of all, it's vitally important that your use of [ ] and { } brackets and braces match the universal standard. OK, just kiddin'.
When looking at leaks, you can assume that the leak is due to a problem in your code but that's not 100% of the fault. In some cases, there may be something happening in Apple's (gasp!) code that is at fault. And it may be something that's hard to find, because it doesn't show up as cocoa objects being allocated. I've reported leak bugs to Apple in the past.
Leaks are sometimes hard to find because the clues you find (e.g. hundreds of strings leaked) may happen not because those objects directly responsible for the strings are leaking, but because something is leaking that object. Often you have to dig through the leaves and branches of a leaking 'tree' in order to find the 'root' of the problem.
Prevention: One of my main rules is to really, really, really avoid ever allocating an object without just autoreleasing it right there on the spot. Anywhere that you alloc/init an object and then release it later on down in the block of code is an opportunity for you to make a mistake. Either you forget to release it, or you throw an exception so that the release never gets called, or you put a 'return' statement for early exit somewhere in the method (something I try to avoid also).
You can build the beta port of Valgrind from here: http://www.sealiesoftware.com/valgrind/
It's far more useful than any static analysis, but doesn't have any special Cocoa support yet that I know of.
Obviously you need to understand the basic memory management concepts to begin with. But in terms of chasing down leaks, I highly recommend reading this tutorial on using the Leaks mode in Instruments.