gdb "watch" command breaks my loop? - gcc

First, I've got a infinite loop like this:
#include<stdio.h>
int main(){
int i=0;
int b=1;
while(b)
{
++i;
printf("%d\n",i);
}
return 0;
}
I tried to compile it, and run inside gdb, and break when "i==10", so I:
gcc 5.c -g && gdb a.out
(gdb) b main
Breakpoint 1 at 0x4005a3: file 5.c, line 3.
(gdb) r
Starting program: /home/console/a.out
Breakpoint 1, main () at 5.c:3
3 int i=0;
(gdb) watch i==10
Hardware watchpoint 2: i==10
(gdb) r
The program being debugged has been started already.
Well, the program seem to be terminated after "r". Why it doesn't break when "i==10"?
Thanks.

When you're watching your auto variable, the debugger needs to have the context available.
When you try to run the program again, gdb warns you: you'll lose the context and thus your hardware watchpoint (auto variables will be deallocated & reallocated).
r/run command runs the program from the start. You're mixing it up with continue. It's just that HW watchpoints on auto variables are cleaned up with a really unclear warning and it runs as infinite loop afterwards
To avoid this, there are several alternatives, all of them having their pros & cons:
just perform c (continue) instead of r: your hw watchpoint will work: cons: you cannot type r (you'll survive)
replace your hardware breakpoint by a conditional breakpoint: b 5.c:9 if i==10 (line 9 is the line of the printf). cons: performance will suffer because the breakpoint will be triggered each time, and gdb decides to interrupt or not depending on the condition
make g i global: allows to do what you wanted (restart) without a warning because in that case i isn't an auto variable. cons: global variables are not the best thing (specially when named i :))

Related

How do I make the debugger break when an exception is thrown in D?

When debugging D code that fails due to an uncaught exception, the exception mechanism unrolls the stack all the way back and then prints a stack trace, leaving us with the somewhat less than helpful:
(gdb) bt
No stack.
The stack trace gives us the line the exception was thrown from, but that's not especially helpful if it doesn't throw until a few thousand iterations in. It would be quite useful to be able to set the debugger to break at the point of an exception whenever one is thrown.
At the moment, the only documentation out there on this seems to be a few posts on the dlang mailing lists. I've found a few approaches that work with my setup, and have included them in my own answer, but for the benefit of others with this problem, I'm hoping we can get a more comprehensive answer that contains approaches for any combination of { dmd, gdc, ldc } x { gdb, lldb }.
since DMD/DRuntime 2.082.0 this is possible by passing the --DRT-trapException=0 flag to your program. The PR that Adam linked in the comments got merged for this.
With that addition you can also force it in your code with a prettier solution than the rt_trapExceptions code:
extern(C) __gshared string[] rt_options = [ "trapExceptions=0" ];
You can read more about configuring the runtime options here: https://dlang.org/phobos/rt_config.html
Before that you were able to set rt_trapExceptions in a custom main as described in This Week in D: August 7, 2016:
extern extern(C) __gshared bool rt_trapExceptions;
extern extern(C) int _d_run_main(int, char**, void*);
extern(C) int main(int argc, char** argv) {
rt_trapExceptions = false;
return _d_run_main(argc, argv, &_main);
}
int _main() {
// your code here
}
All of these were tested on Linux. The -g flag was passed to all three compilers. The -d-debug flag was also passed to ldc, for all the good it did.
gdb
(gdb) break _d_throwdwarf
Works on linux + dmd
Does not work on linux + gdc
Does not work on linux + ldc
(gdb) break _d_throwc
unknown, but the druntime source seems to suggest that this is _d_throwdwarf for win32 and win64. Anyone with a Windows system want to test that?
(gdb) break object.Throwable.this
Works on linux + dmd
Works on linux + gdc
Does not work on linux + ldc
(gdb) catch throw|catch|signal
Does not work on linux + dmd or linux + gdc
lldb
(lldb) b _d_throwdwarf
works on linux + dmd

GDB: how to call functions with modified parameters during debugging

Consider the following trivial Fortran program that adds two integers via a subroutine and prints the result:
PROGRAM MAIN
INTEGER I, J, SUM
I = 1
J = 1
CALL ADD(I, J, SUM)
WRITE(*,*) SUM
END
SUBROUTINE ADD(I, J, SUM)
INTEGER I, J, SUM
SUM = I + J
END
Compiling via gfortran -g -O0 gdb-mwe.f -o gdb-mwe and running in the GNU Debugger, I want to call ADD from the debugger with modified input arguments right before the write output. Here's what happens:
Reading symbols from gdb-mwe...done.
(gdb) break 10
Breakpoint 1 at 0x4007dd: file gdb-mwe.f, line 10.
(gdb) r
Starting program: /home/username/Documents/Fortran/gdb-mwe
Breakpoint 1, MAIN__ () at gdb-mwe.f:10
10 WRITE(*,*) SUM
(gdb) p j = j+1
$2 = 2
(gdb) call add(i,j,sum)
Program received signal SIGSEGV, Segmentation fault.
0x000000000040079a in add (
i=<error reading variable: Cannot access memory at address 0x1>,
j=<error reading variable: Cannot access memory at address 0x2>,
sum=<error reading variable: Cannot access memory at address 0x2>)
at gdb-mwe.f:18
18 SUM = I + J
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on".
Evaluation of the expression containing the function
(add) will be abandoned.
When the function is done executing, GDB will silently stop.
How do I get this right?
As pointed out in the comments, the open bugs in gdb prevents doing this currently.
A possible workaround would be to debug a 32-bit version of the code. This results in some differences, but for simple debugging tasks it may be sufficient.
For intel fortran compilers, this requires only adding the -m32 flag (provided 32-bit libraries have been installed).
For gfortran it seems that installing the multilib package first is necessary, as show in this questions.

How to get backtrace without core file?

In case core-dump is not generated(due to any possible reason). And I want to know back trace (execution sequence of instructions). How Can I do that?
As /proc/pid/maps stores the memory map of a process.
Is there any file in linux which stores userspace or kernel space of a process?(May be I'm using wrong words to express)
I mean to say all address by address sequence of execution of instructions.
To see what the kernel stack for a process looks like at the present time:
sudo cat /proc/PID/stack
If you want to see the user stack for a process, and can get to it while it is still running (even if it is stuck waiting for a system call to return), run gdb and attach to it using its PID. Then use the backtrace command. This will be much more informative if the program was compiled with debug symbols.
If you want backtrace to be printed in Linux kernel use dump_stack()
If you want backtrace to be printed in user-level C code, implement something like this
#include <stdlib.h>
#include <stdio.h>
#include <execinfo.h>
#define BACKTRACE_SIZ 64
void show_backtrace (void)
{
void *array[BACKTRACE_SIZ];
size_t size, i;
char **strings;
size = backtrace(array, BACKTRACE_SIZ);
strings = backtrace_symbols(array, size);
for (i = 0; i < size; i++) {
printf("%p : %s\n", array[i], strings[i]);
}
free(strings); // malloced by backtrace_symbols
}
And then compile the code with -funwind-tables flag and link with -rdynamic
As told in http://www.stlinux.com/devel/debug/backtrace

Confusing debugging error in Fortran program

I've been sitting here for a while quite baffled as to why my debugger keeps displaying an error in my code when the program runs fine. There are three parts to a very simple program that is just reading in information from a file.
My code is broken into three Fortran files given below and compiled via
ifort -o test global.f90 read.f90 test.f90
global.f90:
module global
implicit none
integer(4), parameter :: jsz = 904
end module global
read.f90:
subroutine read(kp,q,wt,swt)
implicit none
integer(4) :: i, j
integer(4), intent(in) :: kp
real(8), intent(out) :: swt, q(kp,3), wt(kp)
swt = 0.0d0; q(:,:) = 0.0d0; wt(:) = 0.0d0
open(7,file='test.dat')
read(7,*) ! Skipping a line
do i = 1, kp
read(7,1000)(q(i,j),j=1,3), wt(i)
swt = swt + wt(i)
end do
close(7)
return
1000 format(3F10.6,1X,1F10.6)
end subroutine read
test.f90:
program test
use global
integer(4) :: i, j
real(8) :: tot, qq(jsz,3), wts(jsz)
call read(jsz,qq,wts,tot)
stop
end program test
The error I keep receiving is
Breakpoint 1, read (kp=904,
q=<error reading variable: Cannot access memory at address 0x69bb80>,
wt=..., swt=6.9531436082559572e-310) at read.f90:6
This error appears right when the subroutine of read is called. In other words, I'm adding a breakpoint at the read subroutine and running the code in gdb after the breakpoint is added. The program will continue to run as expected and give the correct outputs when I include write statements in the 'test' program. However, if I use the gdb print options I receive an error of 'Cannot access memory at address 0x69bb80' for array q only. All other arrays and variables can be displayed with no problems.
As I would like the read subroutine to be a stand alone subroutine and not necessarily use any global parameters, I have not used the global module and instead called the variable kp into the subroutine. I decided to test whether using the global module would help, and if I use jsz in place of kp, I do indeed remove the error. However, since this isn't my overall goal with the subroutine, I would hopefully like to figure out how to fix this without the use of the global module. (I also tried not using the global at all and setting the parameter variable of kp in the test.f90 program directly, but this also gives the error.)
Any insight on possible reasons for this error, or suggestions to try and fix the memory addressing issue would be greatly appreciated.
I think this is an issue specific to the ifort+gdb combination that is fixed with newer gdb versions. Here's a smaller example to reproduce the issue:
$ cat test.f90
subroutine bar(arg)
integer, intent(inout):: arg
print *, 'bar argument is', arg
arg = 42
end subroutine bar
program test
integer:: param
param = 3
call bar(param)
print *, 'post-bar param:', param
end program test
$ ifort -g -O0 -o test test.f90
$ gdb --quiet test
Reading symbols from /home/nrath/tmp/test...done.
(gdb) b 4
Breakpoint 1 at 0x402bd0: file test.f90, line 4.
(gdb) r
Starting program: /home/nrath/tmp/test
[Thread debugging using libthread_db enabled]
Breakpoint 1, bar (arg=#0x2aaa00000003) at test.f90:4
4 print *, 'bar argument is', arg
(gdb) p arg
$1 = (REF TO -> ( INTEGER(4) )) #0x2aaa00000003: <error reading variable>
(gdb) quit
$ gdb --version | head -1
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
However, if you compile with gfortran instead of ifort, or if you use GDB 7.7.1, it works fine.
Did you add the INTERFACE statement to the end of your programme?
You need it when you call a function that is not contained in the programme.

How to get GDB not to print function parameter values when "stepping into"?

When hitting breakpoints and stepping into functions, gdb version 6.8 prints the name of the function followed by the function arguments.
It just so happens, in the program I'm debugging, one of the parameter values is a HUGE record being passed by reference. gdb prints the variable name followed by ALL of its member variables. It literally takes gdb a minute or two to print all the member variables contained in the class... which is really annoying when debugging.
I'm pretty sure there is a setting to disable this behavior, what is that setting?
Found it, finally. To disable the output completely:
set print frame-arguments none
To print only scalar values and ignore arrays & structs:
set print frame-arguments scalars
To turn the printing back on:
set print frame-arguments all
I have a way that I've always done this, but seeing your question made me curious to see if there is a better mechanism. I didn't find anything.
You can always set a breakpoint inside the function you're stepping into, but BEFORE you do the step, use the 'commands' command to tell gdb that you don't want it to print anything at all when it hits that breakpoint. An example will make things clearer...
You'll notice that when I run the program, I stop at the breakpoint on line 10 (the call to foo) and it prints my current context. After issuing the 'commands 2' command and telling gdb to be silent on that breakpoint, nothing is printed at all when I hit it. I did the backtrace (bt) just to show that I was where I wanted to be.
Hope this helps:
> cat tmp.cpp
#include <stdio.h>
void foo(int a)
{
printf ("%d\n", a);
}
int main()
{
foo(0);
return 0;
}
> g++ -g tmp.cpp
> gdb a.out
GNU gdb Fedora (6.8-27.el5)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...
(gdb) break 10
Breakpoint 1 at 0x8048491: file tmp.cpp, line 10.
(gdb) break 5
Breakpoint 2 at 0x804846a: file tmp.cpp, line 5.
(gdb) run
Starting program: /home/ronb/software/a.out
Breakpoint 1, main () at tmp.cpp:10
10 foo(0);
(gdb) commands 2
Type commands for when breakpoint 2 is hit, one per line.
End with a line saying just "end".
>silent
>end
(gdb) c
Continuing.
(gdb) bt
#0 foo (a=0) at tmp.cpp:5
#1 0x0804849d in main () at tmp.cpp:10
(gdb)

Resources