I have a global function in a long run program :
int test()
{
int a = 12;
int c = 10;
printf("a=%d",a);
a += c ;
printf("a=%d", a);
return a;
}
I debug the program and break, then issue the following command:
(lldb) call test()
a=12a=22(int) $0 = 22
(lldb)
I want it to break in test() method every line after I hit call test(), not just return the result immediately. Anyone knows how to do it ?
------------------------------------ Answer Below ------------------------------------
#Jason Molenda 's answer is the right answer,use expr -i0 -- test() instead of call test():
(lldb) b test
Breakpoint 1: 4 locations.
(lldb) expr -i0 -- test()
error: Execution was interrupted, reason: breakpoint 1.1.
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
(lldb)
Now it break in test(), but raise an error!!! How to avoid the error ?
The expression command in lldb (call is an alias for expression) takes a dozen or so options, one of them being whether lldb should stop on a breakpoint while executing the expression, --ignore-breakpoints false, or -i false, or -i 0.
(lldb) br s -n printf
Breakpoint 2: where = libsystem_c.dylib`printf, address = 0x00007fff89ee7930
(lldb) expr -- (void)printf("hi\n")
hi
(lldb) expr -i0 -- (void)printf("hi\n")
error: Execution was interrupted, reason: breakpoint 2.1.
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
Process 15259 stopped
* thread #1: tid = 0xf0daf, 0x00007fff89ee7930 libsystem_c.dylib`printf, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
#0: 0x00007fff89ee7930 libsystem_c.dylib`printf
libsystem_c.dylib`printf:
-> 0x7fff89ee7930: pushq %rbp
0x7fff89ee7931: movq %rsp, %rbp
0x7fff89ee7934: pushq %r15
0x7fff89ee7936: pushq %r14
(lldb)
There was some thought put in to the default behavior (whether to stop on a breakpoint or not), and this seemed the behavior most people would expect.
As I said, the call command is just an alias for expression. If you want to change the behavior of it, you can overwrite the alias with one of your own. e.g. command alias call expr -i false -- will do the trick. You can put this in your ~/.lldbinit file and you'll be set.
It's not a joke? Just checked standard breakpoint to be sure:
(gdb) b test
Breakpoint 2 at 0x400671: file t.c, line 6.
(gdb) call test()
Breakpoint 2, test () at t.c:6
6 printf("a\n");
Related
I use electron/build_tools to build electron and run e init --root=~/electron --bootstrap testing; e debug.(e debug runs local Electron build inside of lldb.)
Set a breakpoint by (lldb) br set --file archive.cc --line 155
Print any variable in this file, eg p header ,p size but return error.
Run frame variable , frame variable -g but no value return.
(lldb) br set --file archive.cc --line 155
(lldb) r
Process 30523 launched: '/Users/electron/src/out/Testing/Electron.app/Contents/MacOS/Electron' (x86_64)
Electron Framework was compiled with optimization - stepping may behave oddly; variables may not be available.
Process 30523 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100352d90 Electron Framework`::Init() at archive.cc:155:63 [opt]
152 }
153
154 base::PickleIterator header_pickle(
-> 155 base::Pickle(reinterpret_cast<const char*>(file_.data() + 8), size));
156 std::string header;
157 if (!header_pickle.ReadString(&header)) {
158 LOG(ERROR) << "Failed to read header string at '" << path_.value() << "'";
Target 0: (Electron) stopped.
(lldb) frame variable
(lldb) p file_
error: <user expression 21>:1:1: use of undeclared identifier 'file_'
file_
^
(lldb) p size
error: <user expression 23>:1:1: reference to overloaded function could not be resolved; did you mean to call it?
size
^~~~
note: possible target for call
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.
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.
I am having a strange problem I do not know how to debug:
I have the following (C++11) class method:
void RamCloud::write(uint32_t tableId, uint64_t id, const void* buf,
uint32_t length,
uint64_t* version, bool async)
{
btree::node_cache& cache = btree::node_cache::instance(104857600);
cache.write(tableId, id, buf, length);
theCloud->write(tableId, id, buf, length, nullptr, version, async);
}
(don't thing too much what the code does, it does not really matter here).
Most of the time this works, but there is one case where it does fail. If I break at the last line using gdb, I can do the following:
(gdb) p theCloud
$3 = (RAMCloud::RamCloud *) 0x7fbe14009e90
(gdb) p tableId
$5 = 3
(gdb) p id
$6 = 3
(gdb) p buf
$7 = (const void *) 0x7fbe253a22d0
(gdb) p length
$8 = 31496
(gdb) p version
$9 = (uint64_t *) 0x0
(gdb) p async
$10 = false
(gdb) s
#0 0x00007fbe220344aa in RAMCloud::RamCloud::write (this=0x0, tableId=0, id=0, buf=0x0, length=0, rejectRules=0x0, version=0x0, async=false) at /local/mpilman/ramcloudarch/ramcloud/src/RamCloud.cc:260
(gdb) p this
$11 = (RAMCloud::RamCloud * const) 0x0
(gdb) p tableId
$12 = 0
(gdb) p id
$13 = 0
(gdb) p buf
$14 = (const void *) 0x0
(gdb) p length
$15 = 0
(gdb) p rejectRules
$16 = (const RAMCloud::RejectRules *) 0x0
(gdb) p version
$17 = (uint64_t *) 0x0
(gdb) p async
$18 = false
So right before the call everything seems ok, but after the call, all arguments (including the this pointer) switch to null. When I try to continue I get of course a segfault...
So my question: what could be here the problem? The caller is in another library than the callee, but these libraries are linked statically (and everything is compiled with the same compiler).
gcc version is 4.6.1. Does anyone have an idea where I could start debugging?
Thanks for any help!
It looks like your stack is being smashed. Tools like Valgrind on *nix or Application Verifier on Windows can be used to find the cause of these memory-related problems.
I can add a breakpoint in GDB with:
b <filename>:<line no>
How can I remove an existing breakpoint at a particular location?
You can list breakpoints with:
info break
This will list all breakpoints. Then a breakpoint can be deleted by its corresponding number:
del 3
For example:
(gdb) info b
Num Type Disp Enb Address What
3 breakpoint keep y 0x004018c3 in timeCorrect at my3.c:215
4 breakpoint keep y 0x004295b0 in avi_write_packet atlibavformat/avienc.c:513
(gdb) del 3
(gdb) info b
Num Type Disp Enb Address What
4 breakpoint keep y 0x004295b0 in avi_write_packet atlibavformat/avienc.c:513
Try these (reference):
clear linenum
clear filename:linenum
You can delete all breakpoints using
del <start_breakpoint_num> - <end_breakpoint_num>
To view the start_breakpoint_num and end_breakpoint_num use:
info break
Use:
clear fileName:lineNum // Removes all breakpoints at the specified line.
delete breakpoint number // Delete one breakpoint whose number is 'number'