I followed this post to print stack trace How to generate a stacktrace when my gcc C++ app crashes . It works well in x86 linux. Can anyone teach me how to make it work on arm-linux?
I am using arm-linux-gcc 4.4.3.
[root#FriendlyARM /]# ./test1
Error: signal 11:
[0x0]
in x86
mickey#mickeyvm:~/Desktop/workspace/test/testCatchSeg/src$ ./test1
Error: signal 11:
./test1(_Z7handleri+0x19)[0x804876d]
[0xedd400]
./test1(_Z3bazv+0x10)[0x80487c2]
./test1(_Z3barv+0xb)[0x80487e1]
./test1(_Z3foov+0xb)[0x80487ee]
./test1(main+0x22)[0x8048812]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x84de37]
./test1[0x80486c1]
This is how I compile for arm-linux
arm-linux-g++ -g -rdynamic ./testCatchSeg.cpp -o testCatchSeg
ARM does not store the return address on the stack when branching to a subroutine but rather expects any function calling subroutines to save the link register to its own stack frame before calling other functions, so it is impossible to follow stack frames without debug information.
I just got backtrace() to work with GCC for ARM. The key for me was compiling with -funwind-tables. Otherwise the stack depth was always 1 (i.e. empty).
Related
How can I validate a newly created instruction using LLVM?
I am new to LLVM and computer architecture.
Created a new instruction of bfloat16 type arithmetic targeting the RISCV-32 architecture.
I was wondering if the output of this arithmetic instruction was correct. And I wanted to verify that the value stored in the float register is in IEEE754 bfloat16 format.
clang-14 -c -g -v --target=riscv32-unknown-elf -march=rv32izfh0p1 -menable-experimental-extensions -I/usr/include -o main.o main.c
riscv32-unknown-elf-gcc -g -o main main.o
I compiled it through the above command, and it was confirmed that the assembly code came out well as shown below.
enter image description here
Then, I tried to run compiled executable file with qemu-riscv32 and debug it using gdb. But an error illegal instruction occurred.
enter image description here
Question
I think an illegal instruction error occurred because QEMU and gdb don't have information about the new instruction I created. Other than modifying QEMU and GDB, is there any way to validate the newly created instruction?
If you extend a CPU architecture by adding new instructions to it, you need to add support for those in not just the toolchain (which will then output code using that new instruction) but also in the CPU implementation itself (so that it can execute the code your compiler now generates). You can do that either on a real hardware CPU, which in practice will start with changes to its RTL which can be tested in simulation; or you can do it on an emulated version of the CPU such as that which QEMU provides. But if you don't have an implementation of a CPU at all that has your new instructions in it, there's no point in having the compiler emit them, because you have nothing that can run the code that compiler produces.
I am trying to debug a program in cuda-gdb. I am able to successfully set breakpoints in code that runs on the host (CPU), but whenever I try to set a breakpoint in code that runs on the GPU, the debugger skips over the breakpoints and gives me the following error:
"warning: Cuda API error detected: cudaLaunchKernel returned (0x7)"
It then continues to successfully execute the rest of the code. How can I make these work?
I was able to get the breakpoints to work based on this answer from NVIDIA dev forums. Namely, in the nvcc compiler options you need to limit the amount of registers used by using the maxrregcount flag, e.g:
nvcc -arch sm_60 -g -G -dc --maxrregcount=64 --compiler-options -Wall -std=c++14 basic.cu
(Note: to see how much registers you have, enter info cuda devices into cuda-gdb and check the Regs/Lane column)
Is there any gcc option I can set that will give me the line number of the segmentation fault?
I know I can:
Debug line by line
Put printfs in the code to narrow down.
Edits:
bt / where on gdb give No stack.
Helpful suggestion
I don't know of a gcc option, but you should be able to run the application with gdb and then when it crashes, type where to take a look at the stack when it exited, which should get you close.
$ gdb blah
(gdb) run
(gdb) where
Edit for completeness:
You should also make sure to build the application with debug flags on using the -g gcc option to include line numbers in the executable.
Another option is to use the bt (backtrace) command.
Here's a complete shell/gdb session
$ gcc -ggdb myproj.c
$ gdb a.out
gdb> run --some-option=foo --other-option=bar
(gdb will say your program hit a segfault)
gdb> bt
(gdb prints a stack trace)
gdb> q
[are you sure, your program is still running]? y
$ emacs myproj.c # heh, I know what the error is now...
Happy hacking :-)
You can get gcc to print you a stacktrace when your program gets a SEGV signal, similar to how Java and other friendlier languages handle null pointer exceptions. See my answer here for more details:
how to generate a stacktace when my C++ app crashes ( using gcc compiler )
The nice thing about this is you can just leave it in your code; you don't need to run things through gdb to get the nice debug output.
If you compile with -g and follow the instructions there, you can use a command-line tool like addr2line to get file/line information from the output.
Run it under valgrind.
you also need to build with debug flags on -g
You can also open the core dump with gdb (you need -g though).
If all the preceding suggestions to compile with debugging (-g) and run under a debugger (gdb, run, bt) are not working for you, then:
Elementary: Maybe you're not running under the debugger, you're just trying to analyze the postmortem core dump. (If you start a debug session, but don't run the program, or if it exits, then when you ask for a backtrace, gdb will say "No stack" -- because there's no running program at all. Don't forget to type "run".) If it segfaulted, don't forget to add the third argument (core) when you run gdb, otherwise you start in the same state, not attached to any particular process or memory image.
Difficult: If your program is/was really running but your gdb is saying "No stack" perhaps your stack pointer is badly smashed. In which case, you may be a buffer overflow problem somewhere, severe enough to mash your runtime state entirely. GCC 4.1 supports the ProPolice "Stack Smashing Protector" that is enabled with -fstack-protector-all. It can be added to GCC 3.x with a patch.
There is no method for GCC to provide this information, you'll have to rely on an external program like GDB.
GDB can give you the line where a crash occurred with the "bt" (short for "backtrace") command after the program has seg faulted. This will give you not only the line of the crash, but the whole stack of the program (so you can see what called the function where the crash happened).
The No stack problem seems to happen when the program exit successfully.
For the record, I had this problem because I had forgotten a return in my code, which made my program exit with failure code.
I am using a bash shell on my Mac OS X. I have fortran95 compiler installed in /sw/bin/gfortran. every time I attempt to access the compiler, I receive
the error:
"Segmentation fault: 11". I cannot call any programs the regular way
i.e. "gfortran program.f90 -o executable_name "
I am not sure about the problem. Even simple programs which print "hello world" to screen will not work.
May be a problem with your installation as already mentioned. A couple things I would try:
Make sure the shared libraries it is compiled against are being found:
otool -L /sw/bin/gfortran
Compile with some switches that might give you more helpful info. I found using the backtrace option really helps especially to debug seg. faults. You might try to compile with some options such as:
gfortran -g -fbounds-check -Wall -fbacktrace program.f90
I have compiled a cpp file with this command line: g++ -g test.cpp
It throws an exception at line 28. I want to investigate the cause by inspecting the variables in lldb. I set a break point at line 28 and run the a.out in lldb.
(lldb) n
Process 84233 stopped
* thread #1: tid = 0xa44b86, 0x00000001000017fb a.out`say(s=<unavailable>) + 987 at so.cpp:28, queue = 'com.apple.main-thread', stop reason = step over
frame #0: 0x00000001000017fb a.out`say(s=<unavailable>) + 987 at so.cpp:28
25 }
26 else{
27 s.insert(0, to_string(sz));
-> 28 s.erase(2, sz-1);
29 }
30 return s;
31 }
(lldb) po s
error: Couldn't materialize: couldn't get the value of variable s: variable not available
Errored out in Execute, couldn't PrepareToExecuteJITExpression
Why the error message? How can I inspect the variable s?
lldb version: lldb-320.4.115.3
g++ version: Configured with: --prefix=/Applications/Xcode6-Beta5.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.45.3) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.3.0
Thread model: posix
That error means the debug information does mention the variable, but says it has no storage location at the current PC.
That can be because the variable got optimized out (unlikely given you are just calling a function on the variable) or because the compiler flubbed the debug info for the variable and lost track of where it went.
Make sure you are compiling the code you are trying to debug at -O0 as there aren't many compilers that emit good debug information at higher optimization levels. If you are compiling at -O0, this is a compiler bug. You should probably report it to the gcc folks. You could see if you have better luck with clang. Otherwise, you have to read the assembly of the function to figure out where the variable actually lives, then tell the debugger to print the appropriately cast address.
I had this problem when I enabled the "Address Sanitizer" from my app scheme. Disable it fixed the issue.
I see this when I run a RELEASE (vs a DEBUG) build (Product->Scheme...->Edit Scheme...->Info, then set Build Configuration to "Debug".
I had this issue when compiling with the flag -Og. For some reason I was thinking that that meant 'optimize for debugging'. I don't think thats the case in reality. Removing that flag fixed the issue for me.