Does any common debugger allow to turn off this automatic initialization of uninitialized vars and members, so that it would be possible to actually see those with debugger?
I'm using gdb right now, the language in my case is C with GCC if it matters.
Edit: this is about local stack variables.
Edit 2: i wrote this question after i found a local structure with garbage in its members which caused crashes. Those crashes were not happening under debugger, which means, garbage or not (maybe special values for uninitialized data), the debugger treats those in a special way and prevents crash. I'd like to find out if this is a feature that can be disabled in any common debugger, gdb most preferably.
Related
I'm working on a fairly involved c program that is using a linked list of structures. There is a global variable declared at the top of one of my .c files (queue_head). This variable is now getting overwritten mysteriously, which causes seg faults.
Is there some way to find out the layout of my variables in memory. My best guess as to the cause is that something is writing past the end of it's memory and overwriting the queue_head memory location.
To test that I reversed the positions of queue_head and queue_tail in my source file, and the next time I ran the program, queue_tail was getting corrupted but queue_head was fine.
Of course it could be an errant pointer, but my belief is that it's something behind it in memory getting written to past it's memory allocation.
Is there a way to see how c maps out the variables short of disassembly?
Variables are generally laid out in order of appearance in file, but if program has several files, then it's harder to predict. You can print their addresses to find possible offender:
printf("%p %p\n", &queue_head, &fishy_var);
But what's good in finding previous variable? It might well happen that broken code doesn't reference it directly.
A better approach is to use debugger. For example if you can run program in gdb, then you can use watchpoint to break at location where memory gets corrupted: watch queue_head. After this program will break every time value of queue_head changes, including legitimate uses. To isolate legitimate uses add dummy pointer variable just before queue_head and watch it:
void *fishy_var;
queue *queue_head;
And then in gdb:
break main
run
watch fishy_var
continue
This should lead right to the offending code.
Note, that you'd better put printf I showed earlier at the start of main, to 1. make sure variables are consecutive in memory and 2. make sure compiler doesn't optimize away unused fishy_var.
From most compilers (or more likely linkers), you can generate a .map file, which will list all global variables and functions.
You don't mention which compiler you use, but for gcc this will answer your question.
Basically, add this to your gcc line:
-Xlinker -Map=output.map
During a discussion today I came across that there are checks in the VxWorks and in LynxOS which tells you that the address you assign for a pointer is from a valid range. This the first time I am hearing about this code like I assign int *i=&variable;.
I should get a warning or error which says that In my application I cannot assign the address value to the integer.
Like while I do a NULL check I am only checking the address 0x00000000. But there can be the case the address might be 0x00000001. Which is also an invalid case if its an unmapped area and might not be accessible. Is any one aware of some thing similar for Linux or can guide how its done in VxWorks or LynxOS.
Any ideas??
The function you seek in VxWorks is called vxMemProbe.
Basically the vxMemProbe libraries insert special exception handling code to catch a page fault or bus error. The vxMemProbe function is used to check if the address is valid for read or write. It also allows you to test if the particular address is accessible with a given data width (8,16,32,64 bits) and alignment.
The underlying mechanism of vxMemProbe is tied to the specific architectures exception handling mechanisms. The vxMemProbe libraries insert code into the exception handlers. When you probe an address that triggers an exception the handler checks to see if vxMemProbe triggered the exception. If so, then the handler restores the state processor prior to the exception and returns execution to where vxMemProbe was called while also returning value via the architectures given calling conventions.
In general you can't do what you want, as explained in Felix Palmen's answer.
I should get a warning or error which says that In my application I cannot assign the address value to the integer.
Statically and reliably detecting all pointer faults is impossible (because it could be proven equivalent to solving the halting problem). BTW you might consider using static program analysis tools like Frama-C.
On Linux, in principle, you might test at runtime if a given address is valid in your virtual address space by e.g. using /proc/, e.g. by parsing the /proc/self/maps pseudo textual file (to understand what I mean try cat /proc/$$/maps in a terminal, then cat /proc/self/maps). See proc(5). In practice I don't recommend doing that often (it probably would be too slow), and of course it is not a builtin function of the compiler (you should code it yourself). BTW, be aware of ASLR.
However, there are tools to help detect (some of) the faulty address uses, in particular valgrind and the address sanitizer facility, read about instrumentation options of GCC and try to compile with -fsanitize=address ...
Don't forget to compile your code with all warnings and debug info, so use gcc -Wall -Wextra -g to compile it.
BTW, if you store in some global pointer the address of some local variable and dereference that pointer after that local variable is in scope, you still have some undefined behavior (even if your code don't crash, because you usually dereference some random address on your call stack) and you should be very scared. UB should be always avoided.
There are several misconceptions here:
From the perspective of the language C, there's only one pointer value that's guaranteed to be invalid, and this is NULL. For other values, it depends on the context. A pointer is valid when it points to an object that is currently alive. (Note that this is trivially true in your int *i = &variable example, as this is only valid syntax when there is a variable accessible from your current scope)
NULL does not necessarily mean a value with all bits zero. This is the most common case, but there can be platforms that use a different bit pattern for the NULL pointer. It's even allowed by the C standard that pointers of different types have different representations for NULL. Still, converting 0 to a pointer type is guaranteed to result in the NULL pointer for this type.
I don't know what exactly you're referring to in VxWorks, but of course Linux checks memory accesses. If a process tries to access an address that's not mapped in the virtual address space, this process is sent a SIGSEGV signal, which causes immediate abnormal program termination (Segmentation fault).
How would I go about writing a C program that lists ALL the contents of stack and heap including its own variables and mallocations ?
The purpose of it is for me to be able to see what's going on in the memory as I write and test code.
The c standard doesn't explicitly mention a stack or a heap. That, along with the fact that variable and function names are compiled out, means that your task is impossible.
You could build your own compiler which would effectively be a debugging tool. But that would be ridiculous as such a thing would take a long time to build and you'd have to adapt it constantly as the standard evolves. Or you could use the output of a compiler that generates debugging symbols.
Better still, learn to use a good debugger.
I am working on a large C project for a company.
I have realized that some times in the compiled executable, static variables used in C files are not initialized to zero and have some value in them.
But when I edit the code a bit, like adding a print statement any where in the project, the issue is resolved.
I am using a Broadcom STB mips cross-compiler toolchain for compiling the codes.
The program is run on a Broadcom 97241 chipset running Linux 3.1.3.
[EDIT] I tried a clean build also but the problem did not go away.
The C standard requires that static variables must be initialized at the start of the program. If you don't initialize them, then the compiler will initialize them to 0. So if you are using normal compiler, then all your static variables are initialized to 0 if you don't initialize them explicitly. Such problems may occur if:
1) Some of your code set the value to a static variable.
2) The compiler is not C compiler.
3) Your program damage the memory and then you can't rely on assertions, on printf(), e.t.c.
Anyway. Try to initialize static variables to 0 explicitly. (to cut the 2 point off). And hope there is a way to debug your application. Debugger is much more useful in such problems, then asking such abstract question here.
As already has been stated, the static variables are set to 0 by the compiler. If you see some different behaviour it is most likley your code corrupting it somewhere (i.e. array overrun or similar).
In order to track this problem you should set a breakpoint on main and verify that the variables are indeed 0. If not, it would be a compiler bug.
If the variable is 0 then set a memory access breakpoint on it and you should see where you are corrupting it.
Without seeing the code it's really not helpfull to ask here, as any answer is just guessing, so we can only provide generic answers.
Variables declared as static should be initialised to 0, because the bss should be initialised to 0 on startup.
Adding printf statements and having the problem go away sounds like it could be a memory corruption issue. Are you accessing an array out of bounds, overflowing the stack, etc?
I've been chasing down a crash that seems to be due to memory corruption. The setting is C, building using llvm for iOS.
The memory corruption is absent in debug mode and with optimization level 0 (-O0). In order to be able to step through the code, I've rebuilt with debug symbols but optimization level 1 (-O1). This is enough to reproduce the crash and it allows me to step through the program.
I've narrowed the problem down to a particular function call. Before it, the value of a certain pointer is correct. After it, the value is corrupted (it ends up equalling 0x02, for whatever that is worth).
Lldb doesn't seem to want to watch variables or memory locations. Switching to gdb, I find that if I try to print the address of the aforementioned variable I encounter the following message: "Address requested for identifier 'x' which is in register $r4".
I understand that, as an optimization, the compiler may decide to keep the value of a variable in a register. True enough, if I print the value of $r4 before and after the function call, I see the correct value before and 0x02 after.
I'm in a bit over my head at this point and not sure how to split this into smaller problems. My questions are therefore these:
assuming that the compiler is storing the value of a variable in a register as an optimization, what is supposed to happen to that register when another function is invoked?
Is there some mechanism whereby the value is stored and restored once the new function returns?
Any recommendations on debugging techniques?
All help and suggestions appreciated. Links to reading material on the subject also quite welcome.
Thanks
EDIT: adding version information
iOS version: 5.1
llvm version: i686-apple-darwin10-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2377.00)
Xcode version: 4.3.1
Gdb version: GNU gdb 6.3.50-20050815 (Apple version gdb-1708)
Running on an iPhone 3Gs (crash does not appear in simulator)
Not a full answer, but
assuming that the compiler is storing the value of a variable in a
register as an optimization, what is supposed to happen to that
register when another function is invoked?
The register should probably be pushed to the stack by the callee.
Is there some mechanism whereby the value is stored and restored once
the new function returns?
Depends on the calling conventions, but in general - whoever pushed it to stack is responsible to pop it from the stack
Last thing:
If you meet such case, where "it works" on some optimisation level and doesn't on other, you are very likely to have an undefined behavior. If you can't find it in your code, you can ask it here, giving the actual code.
Try using Valgrind if possible. This looks like a good starting point.
Also, try enabling -fstack-protector for your program.