Does an automatic "print locals" command exist in gdb? - c++

Is there a gdb command that does what info locals does but automatically (i.e after every step or breakpoint)? I find info locals to be very essential, but I would much rather not have to type it everytime. It would be a bummer if something like that is not implemented.
Also I'm not looking to "watch" or "display" a specific variable or two. Display all, everytime, that's what I'm looking for.

Display all, everytime, that's what I'm looking for.
(gdb) define hook-stop
info locals
end
Example:
// foo.c
int foo()
{
int z = 1;
int zz = 2;
int zzz = 3;
return z + zz + zzz;
}
int main()
{
int x = 42;
int y = 24;
foo();
return x;
}
gcc -g foo.c && gdb -q ./a.out
(gdb) define hook-stop
Type commands for definition of "hook-stop".
End with a line saying just "end".
>info locals
>end
(gdb) start
Temporary breakpoint 1 at 0x1159: file foo.c, line 11.
Starting program: /tmp/a.out
x = 0
y = 0
Temporary breakpoint 1, main () at foo.c:11
11 int x = 42;
(gdb) n
x = 42
y = 0
12 int y = 24;
(gdb) n
x = 42
y = 24
13 foo();
(gdb) s
z = 21845
zz = 1431654784
zzz = 0
foo () at foo.c:3
3 int z = 1;
(gdb) n
z = 1
zz = 1431654784
zzz = 0
4 int zz = 2;
(gdb) n
z = 1
zz = 2
zzz = 0
5 int zzz = 3;
(gdb) n
z = 1
zz = 2
zzz = 3
6 return z + zz + zzz;
(gdb) n
z = 1
zz = 2
zzz = 3
7 }
(gdb)
x = 42
y = 24
main () at foo.c:14
14 return x;
(gdb) q
Documentation here.

Related

string iterator not stopping at end of string

I'm reading yummy recipes from a line made of different substrings divided by ; in this order:
Recipe index (R1)
Number to be cooked (1)
Recipe name (Ensalada Mixta)
Ingredients and their quantity (Lechuga 200;...)
The first three work like a charm, you can see they are stored in the data array and printed in the printf block. The problem comes reading the rest. The reader iterator reads through the line perfectly but doesn't stop at the end, so it add rubbish values to the pair and throws a segfault. Here's the output from this MRE:
:: R1
:: 1
:: Ensalada Mixta
-> Lechuga 200
-> Tomate 50
-> Pepino 50
-> Cebolla 50
-> Aceite Oliva 5
-> Vinagre De Vino 10
-> Sal 1
[1] 85313 segmentation fault (core dumped)
The loop should stop after Sal 1, so what am I doing terribly wrong? Here's the code:
#include <cmath>
#include <list>
#include <string>
#include <utility>
#include <cstdio>
using namespace std;
int main () {
string line = "R1;1;Ensalada Mixta;Lechuga 200;Tomate 50;Pepino 50;Cebolla 50;Aceite Oliva 5;Vinagre De Vino 10;Sal 1";
list<pair<string, unsigned> > ings;
string recipe_data[3];
string::const_iterator reader = line.cbegin();
//Lectura del código, plato y ing_name de la receta
for (int i = 0; i < 3; ++reader) {
if (*reader != ';')
recipe_data[i].push_back(*reader);
else
++i;
}
printf(":: %s\n", recipe_data[0].c_str());
printf(":: %s\n", recipe_data[1].c_str());
printf(":: %s\n", recipe_data[2].c_str());
/*
* This is the problematic loop. The problem is in the while boolean
* expression, which always evaluates to false.
*/
while (reader != line.cend()) {
string ing_name = "";
unsigned ing_quantity = 0;
while (*reader != ';' && reader != line.cend()) {
ing_name += *reader;
++reader;
}
string::reverse_iterator it = ing_name.rbegin();
for (int i = 0; *it != ' '; i++) {
char c[1] = {*it};
ing_quantity += atoi(c) * pow(10, i);
++it;
ing_name.pop_back();
}
ing_name.pop_back();
pair<string, unsigned> ing(ing_name, ing_quantity);
ings.push_back(ing);
printf("-> %s %d\n", ing.first.c_str(), ing.second);
++reader;
}
}
Here's gdb output using a breakpoint on the very last ++reader line:
Breakpoint 1, main () at so.cpp:52
52 ++reader;
1: reader = 59 ';'
2: line.cend() = 0 '\000'
3: ing = {first = "Tomate", second = 50}
(gdb)
Continuing.
-> Pepino 50
Breakpoint 1, main () at so.cpp:52
52 ++reader;
1: reader = 59 ';'
2: line.cend() = 0 '\000'
3: ing = {first = "Pepino", second = 50}
(gdb)
Continuing.
-> Cebolla 50
Breakpoint 1, main () at so.cpp:52
52 ++reader;
1: reader = 59 ';'
2: line.cend() = 0 '\000'
3: ing = {first = "Cebolla", second = 50}
(gdb)
Continuing.
-> Aceite Oliva 5
Breakpoint 1, main () at so.cpp:52
52 ++reader;
1: reader = 59 ';'
2: line.cend() = 0 '\000'
3: ing = {first = "Aceite Oliva", second = 5}
(gdb)
Continuing.
-> Vinagre De Vino 10
Breakpoint 1, main () at so.cpp:52
52 ++reader;
1: reader = 59 ';'
2: line.cend() = 0 '\000'
3: ing = {first = "Vinagre De Vino", second = 10}
(gdb)
Continuing.
-> Sal 1
Breakpoint 1, main () at so.cpp:52
52 ++reader;
1: reader = 0 '\000'
2: line.cend() = 0 '\000'
3: ing = {first = "Sal", second = 1}
(gdb) n
47 pair<string, unsigned> ing(ing_name, ing_quantity);
1: reader = 0 '\000'
2: line.cend() = 0 '\000'
3: ing = {first = "Sal", second = 1}
(gdb)
29 string ing_name = "";
1: reader = 0 '\000'
2: line.cend() = 0 '\000'
3: ing = {first = "Sal", second = 1}
(gdb)
28 while (reader != line.cend()) {
1: reader = 0 '\000'
2: line.cend() = 0 '\000'
(gdb)
29 string ing_name = "";
1: reader = 0 '\000'
2: line.cend() = 0 '\000'
3: ing = {first = "Sal", second = 1}
As you can see, it shouldn't have re-entered the loop since the iterator and cend() are equal, right?
The inner while increments until either you find ; or cend and in both cases you continue. Only on the next iteration you stop because reader != line.cend() is false but thats already too late.
Also you have to first check if you are at the end, and only then dereference reader:
while (reader != line.cend() && *reader != ';') {
ing_name += *reader;
++reader;
}
if (reader == line.cend()) break;

How to step and execute more commands inside a gdb breakpoint's command

Whenever a command is defined for a breakpoint, it can't perform e.g: steps otherwise the following commands don't execute.
code example:
[/tmp]$ cat a.c
void increment(int* x) {
*x = (*x) + 1;
}
int main() {
int a = 1;
for (int i = 0; i < 10; i++)
increment(&a);
return 0;
}
[/tmp]$ gcc --std=c99 a.c -O0 -g
[/tmp]$ gdb a.out
gdb:
(gdb) b increment
Breakpoint 1 at 0x10000600: file a.c, line 2.
(gdb) command 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>p *x
>n
>p *x
>end
(gdb) r
Starting program: /tmp/a.out
Breakpoint 1, increment (x=0x3ffffffff670) at a.c:2
2 *x = (*x) + 1;
$1 = 1
3 }
(gdb) p *x
$2 = 2
It executed the p *x and the n, but not the command after n that was the p *x.
It also happens with c, fin, s...
I found a way out, but it's a workaround....
Let's rethink that gdb script I was writing:
(gdb) b increment
Breakpoint 1 at 0x10000600: file a.c, line 2.
(gdb) command 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>p *x
>n
>end
(gdb) r
Starting program: /tmp/a.out
Breakpoint 1, increment (x=0x3ffffffff670) at a.c:2
2 *x = (*x) + 1;
$1 = 1
3 }
(gdb) b
Breakpoint 2 at 0x1000061c: file a.c, line 3.
(gdb) command 2
Type commands for breakpoint(s) 2, one per line.
End with a line saying just "end".
>p *x
>end
(gdb) p *x
$2 = 2
(gdb) c
Continuing.
Breakpoint 1, increment (x=0x3ffffffff670) at a.c:2
2 *x = (*x) + 1;
$3 = 2
Breakpoint 2, increment (x=0x3ffffffff670) at a.c:3
3 }
$4 = 3
(gdb)
So basically if I need to do anything else after a n, s, fin... I define a break after that and a new command for this new breakpoint that will do whatever I wanted to after.

How to use GDB to monitor two different variables with the same name

I need to use GDB to monitor two different variables with the same name, one of which is a global variable, while the other is a local variable. Any solution?
Consider the following example:
int foo;
void bar()
{
foo++;
}
int main()
{
int foo;
for (foo = 0; foo < 5; foo++) {
bar();
}
return 0;
}
gcc -g t.c
gdb -q ./a.out
(gdb) start
Temporary breakpoint 1 at 0x40050a: file t.c, line 11.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at t.c:11
11 for (foo = 0; foo < 5; foo++) {
(gdb) p &foo
$1 = (int *) 0x7fffffffdccc
(gdb) watch -l foo
Hardware watchpoint 2: -location foo
Note: above watch is set on local foo.
(gdb) p &::foo
$2 = (int *) 0x60103c <foo>
(gdb) watch -l ::foo
Hardware watchpoint 3: -location ::foo
Note: above watch is set on global foo.
(gdb) c
Continuing.
Hardware watchpoint 3: -location ::foo
Global foo has been modufied inside bar().
Old value = 0
New value = 1
bar () at t.c:6
6 }
(gdb) c
Continuing.
Hardware watchpoint 2: -location foo
Local foo has been modified inside main:
Old value = 0
New value = 1
0x0000000000400521 in main () at t.c:11
11 for (foo = 0; foo < 5; foo++) {
(gdb) c
Continuing.
Hardware watchpoint 3: -location ::foo
Old value = 1
New value = 2
bar () at t.c:6
6 }
(gdb) c
Continuing.
Hardware watchpoint 2: -location foo
Old value = 1
New value = 2
0x0000000000400521 in main () at t.c:11
11 for (foo = 0; foo < 5; foo++) {
... etc.

Unable to access all the related predicates in Prolog from C++

I am trying to access all the related predicates of a prolog file from C++.
I have the prolog file as,
"new_gryffindor.pl"
sits_right_of(parvati,lavender).
sits_right_of(lavender,neville).
sits_right_of(neville,alicia).
sits_right_of(alicia,fred).
sits_right_of(fred,george).
sits_right_of(george,lee).
sits_right_of(lee,dennis).
sits_right_of(dennis,dean).
sits_right_of(dean,ginny).
sits_right_of(ginny,angelina).
sits_right_of(angelina,seamus).
sits_right_of(seamus,colin).
sits_right_of(colin,harry).
sits_right_of(harry,hermoine).
sits_right_of(hermoine,ron).
sits_right_of(ron,natalie).
sits_right_of(natalie,katie).
sits_right_of(katie,parvati).
sits_left_of(X,Y) :- sits_right_of(Y,X).
are_neighbours_of(X,Y,Z) :- sits_left_of(X,Z),
sits_right_of(Y,Z).
next_to_each_other(X,Y) :- sits_left_of(X,Y);
sits_right_of(X,Y).
And I have integrated C++ and Prolog file with the C++ code,
term_t a = PL_new_term_ref();
term_t b = PL_new_term_ref();
term_t ans = PL_new_term_ref();
PL_put_variable(ans);
predicate_t p_consult = PL_predicate("consult", 1, "database");
term_t t = PL_new_term_ref();
PL_put_string_chars(t, "new_gryffindor.pl");
PL_call_predicate(NULL, 0, p_consult, t);
fun = PL_new_functor(PL_new_atom("sits_right_of"),2);
PL_cons_functor(ans, fun, a, b);
char *fact1;
char *fact2;
if(PL_call(ans, NULL)) {
PL_get_atom_chars(a, &fact1);
PL_get_atom_chars(b, &fact2);
cout << fact1 << " sits right of " << fact2;
}
This C++ Code is giving me the result for the very first predicate of "sits_right_of" ,i.e, as "parvati sits right of lavender". But I want to print all the related predicates of "sits_right_of" in C++ like the prolog which gives next similar predicate's values by using semicolon ";".
sits_right_of(X,Y).
X = parvati,
Y = lavender ;
X = lavender,
Y = neville ;
X = neville,
Y = alicia ;
X = alicia,
Y = fred ;
X = fred,
Y = george ;
X = george,
Y = lee ;
X = lee,
Y = dennis ;
X = dennis,
Y = dean ;
X = dean,
Y = ginny ;
X = ginny,
Y = angelina ;
X = angelina,
Y = seamus ;
X = seamus,
Y = colin ;
X = colin,
Y = harry ;
X = harry,
Y = hermoine ;
X = hermoine,
Y = ron ;
X = ron,
Y = natalie ;
X = natalie,
Y = katie ;
X = katie,
Y = parvati.
I tried looping statements in C++ but it is printing the same output for multiple times..
So please help me out to print the values of other similar predicates of prolog file in C++.

passing multiple statements in ocaml using "in" and "and" operations

I wanted to convert this C++ code to ocaml, but i'm getting syntax error
C++ code
int** matrix(int n,int **a,int**b)
{
t=n/2;
a11=new int*[t];
for(i=0;i<t;i++)
a11[i]=new int [t];
for(i=0;i<t;i++)
for(j=0;j<t;j++)
a11[i][j]=a[i][j];
a12=new int*[t];
for(i=0;i<t;i++)
a12[i]=new int [t];
for(i=0;i<t;i++)
for(j=0;j<t;j++)
a12[i][j]=a[i][j+t];
a21=new int*[t];
for(i=0;i<t;i++)
a21[i]=new int [t];
for(i=0;i<t;i++)
for(j=0;j<t;j++)
a21[i][j]=a[i+t][j];
}
Ocaml code
let matrix n x y =
let t = n/2 in
let a11 = Array.make_matrix t t 0 in
for i = 0 to t-1 do
for j = 0 to t-1 do
a11.(i).(j) <- x.(i).(j)
done
done
and
a12 = Array.make_matrix t t 0 in
for i = 0 to t-1 do
for j = 0 to t-1 do
a12.(i).(j) <- x.(i).(j+t)
done
done
and
a21 = Array.make_matrix t t 0 in
for i = 0 to t-1 do
for j = 0 to t-1 do
a21.(i).(j) <- x.(i+t).(j)
done
done
;;
The problem is that the value of t is not getting passed inside the a12 and a21 arrays and it is getting unbounded.
The and for a let can't appear in the body of the let. Instead, use multiple lets:
let matrix n x y =
let t = n/2 in
let a11 = Array.make_matrix t t 0 in
for i = 0 to t-1 do
for j = 0 to t-1 do
a11.(i).(j) <- x.(i).(j)
done
done;
let a12 = Array.make_matrix t t 0 in
for i = 0 to t-1 do
for j = 0 to t-1 do
a12.(i).(j) <- x.(i).(j+t)
done
done;
let a21 = Array.make_matrix t t 0 in
for i = 0 to t-1 do
for j = 0 to t-1 do
a21.(i).(j) <- x.(i+t).(j)
done
done
Just to clarify, the following has the same problem as your original code:
# let x = 4 in () and y = 7 in ();;
Error: Syntax error
Since let defines an expression, this amounts to writing () and (), which indeed is not legal OCaml.
The correct use of let ... and looks like this:
# let x = 4 and y = 7 in ();;
Warning 26: unused variable x.
Warning 26: unused variable y.
- : unit = ()
There are several let ... and let ... but just one in.