On debug of c program - c

I have a C program which throws segfault. However, as I use gdb to find out where the error is thrown. I get following stack info... I dont understand why #1 points to ??(). What is the possible reason for this? Thanks.
#0 __longjmp () at ../sysdeps/i386/__longjmp.S:68
#1 0x43746a57 in ?? ()

In order to debug your program, you need to compile it with debugging symbols included, which you can do by using the -g3 flag if compiling using GCC. When you run the debug version of your program in GDB and execute bt (for "backtrace") you should get a more sensible piece of output.

gdb doesn't know the name of the function so it puts ??.
have you tried compiling with debug symbols?

If longjmp() goes astray as it seems it is, then the problem is likely that you're abusing it - either by passing a jmpbuf that was never initialized by a setjmp() call, or by passing a jmpbuf that was set in a routine that has since returned.
For how to find out more with debugging information, see the other answers and compiling with the -g option.

Related

Why gcc -g doesn't work with multiple files

To debug my C code I compile it with the -g flag and use lldb to see where my seg fault is for example.
I use the -g flag so the output of lldb is in C not Assembly.
but now I have a multiple files project and lldb shows only Assembly even tho I'm using the -g flag, it's like the -g flag applies only to one file.
Example:
gcc -g example.c
lldb a.out
>run
I get c code here
gcc -g example1.c example2.c main.c
lldb a.out
>run
I get assembly code here
Can anyone tell me what I'm I missing here?
and how can I get c code in lldb.
Thanks in advance.
When you just run the program you shouldn't be getting code at all.
You will be getting code if the program stops running. Then you need to look at the call stack to make sure you're actually in your own code.
If you're in library code then it will likely not have source available and you'll get assembler code. Go up the call-stack until you reach your own code.
GNU’s documentation for the ‘gcc -g’ says
Produce debugging information in the operating system’s native format (stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging information.
Notice that it makes no mention of either C or assembler.
I imagine that in your first example the error was in your C code; in your second example the error was in a library, such as stdio, for which the debugger doesn’t have C source.
A segmentation fault corresponds to an invalid address. This might mean that you passed invalid data to a library that was expecting a pointer, or you passed a pointer to a buffer but an incorrect length.
A typical error that might cause this is passing a value (v) to a library that is expecting a pointer (&v).

Easiest way to locate a Segmentation Fault

I encountered my first Segmentation Fault today (newbie programmer). After reading up on what a segmentation fault is (Thanks for all of the helpful info on this site, as well as Wikipedia's lengthy explanation), I'm trying to determine the easiest way to go about finding where my fault is occuring. It's written in C and the error is occuring on a *NIX based system (I'm not sure which one to be honest... 99% sure it's Linux). I can't exactly post my code as I have numerous files that I'm compiling that are all quite lengthy. I was just hoping for some best practices you have all observed. Thanks for your help.
P.s. I'm thinking the error is coming from dereferencing a NULL pointer or using an uninitialized pointer. However, I could definitely be wrong.
Use a debugger, such as gdb or if this is not applicable a strace tool to get a better insight into where the segfault occurs.
If you use gcc, make sure you compile with -g switch to include debugging information. Then, gdb will show you the exact location in a source code where it segfaults.
For example, if we have this obvious segfaulty program:
new.c
#include <stdio.h>
int main()
{
int *i = 0x478734;
printf("%d", *i);
}
We compile it with gcc -g new.c -o new and then run the gdb session with gdb new:
We issue the run command in the interactive session and the else is clear:
(gdb) run
Starting program: /home/Tibor/so/new
[New Thread 9596.0x16a0]
[New Thread 9596.0x1de4]
Program received signal SIGSEGV, Segmentation fault.
0x0040118a in main () at new.c:6
6 printf("%d", *i);
(gdb)
As DasMoeh and netcoder have pointed out, when segfault has occured, you can use the backtrace command in the interactive session to print a call stack. This can aid in further pinpointing the location of a segfault.
The easiest way is to use valgrind. It will pinpoint to the location where the invalid access occours (and other problems which didn't cause crash but were still invalid). Of course the real problem could be somewhere else in the code (eg: invalid pointer), so the next step is to check the source, and if still confused, use a debugger.
+1 for Tibors answer.
On larger programs or if you use additional libraries it may also be useful look at the backtrace with gdb: ftp://ftp.gnu.org/pub/old-gnu/Manuals/gdb/html_node/gdb_42.html
I reopen this posts for people passing here since I've just corrected a segfault I've made using gcc.
You should consider using the flag -fsanitize=address which can sometimes highlight your segfault with high precision.

How to debug a crash before main?

My program links statically to many libraries and crashes before getting to main in GDB. How do I diagnose what the problem is?
It's a good bet that LD_DEBUG can help you here. Try this: LD_DEBUG=all ./a.out. This will allow you to easily identify the library which is being loaded when your program crashes.
(Edit: if it wasn't clear, a.out is meant to refer to a generic binary file -- in this case, replace it with the name of your executable).
Edit 2:
To clarify, LD_DEBUG is an environment variable which is examined by the dynamic linker when a program begins execution. If LD_DEBUG is set to some value, the dynamic linker will output a lot of information about the dynamic libraries being loaded during program execution, symbol binding, and so on.
For starters, execute the following on your machine:
LD_DEBUG=help ls
You will see the valid options for LD_DEBUG on your system listed. The most verbose setting is all, which will display all available information.
Now, to use this is as simple as the ls example, only replace ls with the name of your program. There is no need for gdb in order to use LD_DEBUG, as it is functionality provided solely by the dynamic linker, and not by gdb.
It may crash because some component throws an exception and nobody catches it since main() hasn't been entered yet. Set a breakpoint on throwing an exception:
catch throw
run
(If catch throw doen't work the first time you start it, run it once to let it load the dynamic libraries and then do catch throw and run again).
This post has the answer, you have to set a breakpoint before main in the crt0 startup code:
Using GDB without debugging symbols on x86?
starti
starti breaks at the very first instruction executed, see also: Stopping at the first machine code instruction in GDB
An alternative if your GDB is not new enough:
break _start
if you know the that the name of the entry point method is _start, or:
info files
search for Entry point:
Entry point: 0x400440
and run:
break *0x400440
TODO: find out how to compile crt* objects with debug symbols and step into them: How to compile my own glibc C standard library from source and use it?
Start taking the libraries out one by one until it stops crashing.
Then examine the culprit.
I haven't run into this in C but if you link to a c++ library static initialization can crash. You can create it easily by having an assert in a constructor of a static scope variable.
If you can, link your program dynamically instead of statically and follow #denniston.t answer. Maybe debug trace from dynamic linker will help to fix this problem.

How do I know which illegal address the program access when a segmentation fault happens

Plus, The program runs on a arm device running Linux, I can print out stack info and register values in the sig-seg handler I assign.
The problem is I can't add -g option to the source file, since the bug may won't reproduce due to performance downgrade.
Compiling with the -g option to gcc does not cause a "performance downgrade". All it does is cause debugging symbols to be included; it does not affect the optimisation or code generation.
If you install your SIGSEGV handler using the sa_sigaction member of the sigaction struct passed to sigaction(), then the si_addr member of the siginfo_t structure passed to your handler contains the faulting address.
I tend to use valgrind which indicates leaks and memory access faults.
This seems to work
http://tlug.up.ac.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV
static void signal_segv(int signum, siginfo_t* info, void*ptr) {
// info->si_addr is the illegal address
}
If you are worried about using -g on the binary that you load on the device, you may be able to use gdbserver on the ARM device with a stripped version of the executable and run arm-gdb on your development machine with the unstripped version of the executable. The stripped version and the unstripped version need to match up to do this, so do this:
# You may add your own optimization flags
arm-gcc -g program.c -o program.debug
arm-strip --strip-debug program.debug -o program
# or
arm-strip --strip-unneeded program.debug -o program
You'll need to read the gdb and gdbserver documentation to figure out how to use them. It's not that difficult, but it isn't as polished as it could be. Mainly it's very easy to accidentally tell gdb to do something that it ends up thinking you meant to do locally, so it will switch out of remote debugging mode.
You may also want to use the backtrace() function if available, that will provide the call stack at the time of the crash. This can be used in order to dump the stack like it happens in an high level programming language when a C program gets a segmentation fault, bus error, or other memory violation error.
backtrace() is available both on Linux and Mac OS X
If the -g option makes the error disappear, then knowing where it crashes is unlikely to be useful anyway. It's probably writing to an uninitialized pointer in function A, and then function B tries to legitimately use that memory, and dies. Memory errors are a pain.

__libc_lock_lock is segfaulting

I am working on a piece of code which uses regular expressions in c.
All of the regex stuff is using the standard regex c library.
On line 246 of regexec.c, the line is
__libc_lock_lock(dfa->lock);
My program is segfaulting here and I cannot figure out why. I was trying to find where __libc_lock_lock was defined and it turns out it is a macro in bits/libc-lock.h. However, the macro isnt actually defined to be anything, just defined.
Two questions:
1) Where is the code that is run when __libc_lock_lock is called (I know it must be
replaced with something but I dont know where that would be.
2) if dfa is a re_dfa_t object which is casted from a c string which is the buffer member of the regex_t object type, it will not have any member lock. Is this what is supposed to happen.
It really seams like there is some kind of magic going on here with this __libc_lock_lock
If the segfault is in libc then you can be 99.9% sure of the following:
You are doing something wrong with the API
You have at some previous point clobbered or corrupted memory used by libc, and this is a delayed effect. (Thanks Tyler!)
You are doing something that is pushing the API's capability
You are a developer testing the current trunk with new changes in the API implementation
I suspect that the first is the cause. Posting your API usage and your library version might help. The Regexp API in libc is pretty stable.
Look up debugging with gdb to find a stack trace of the execution path leading to the segfault, and install the glibc-devel packages for the symbols. If the segfault is in (or out) of libc ... then you have done something bad (not initialized an opaque pointer for example)
[aiden#devbox ~]$ gdb ./myProgram
(gdb) r
... Loads of stuff, segfault info ..
(gdb) bt
Will print the stack and function-names that led to the segault. Compile your source with the '-g' debug flag to keep important debugging information.
Get an authoritative source for API usage/examples!
Good Luck
In answer to your first question:
The macro is defined in the libc-lock.h; its relative path is sysdeps/mach/bits on
the glibc release I use (2.2.5). Lines 67/68 from that file are
/* Lock the named lock variable. */
#define __libc_lock_lock(NAME) __mutex_lock (&(NAME))
Run your code in gdb until you get to the segfault. Then do a backtrace to find out where it was.
Here is the set of commands you will type to do this:
gdb myprogram
run
***Make it crash***
backtrace
Typing backtrace will print the call stack and will show you what path the code has taken to get to the point where it is segfaulting.
You can go up and down in the stack to your code by typing 'up' or 'down' respectively. Then you can examine variables in that scope.
So for instance, if your backtrace command prints this:
linux_black_magic
more_linux
libc
libc
yourcode.c
Type 'up' a few times so that the stack frame is in your code instead of linux's. You can then examine variables and memory that your program is operating on. Do this:
print VariableName
x/10 &Variable
That will print the value of the variable and then will print a hex dump of memory starting at the variable.
Those are some general techniques to use with gdb and debugging, post more details for more detailed answers.

Resources