Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2017-02-13 Thread Roman Popov via lldb-dev
Thank you very much Greg and Pavel for help!

I will probably need another months or so to work on my variable tracing
stuff. I don't see any additional roadblocks yet.

2017-02-13 22:11 GMT+03:00 Greg Clayton :

> Clang just doesn't currently know where to look for the standard headers.
> Not sure if this is a top level code only bug or not. I know the expression
> parser can include common C headers on Darwin. Not sure if any includes
> work on linux. Try importing  and see how that goes?
>
> The better way to do what you want is to write a shared library, save it
> to "/tmp/liba.so" and then load it at runtime:
>
> (lldb) process load /tmp/liba.so
>
> This will load a shared library with all of the top level code you want
> into your current program, then you can call any functions in that shared
> library as well using expressions that you need.
>
> If you feel you still need to use the expression parser, then a few tips
> on the expression parser when not in top level code mode:
> - C++ lambda functions that don't capture anything can be cast to function
> pointer types and used as static callbacks.
> - Any variable you define that is prefixed with a '$' will become a global
> variable and persist beyond your expression (assign a function callback
> from C++ lambda, and you have a callback you can now use.
> - Any type you declare that is prefixed with a '$' will persist beyond
> that expression and be available for future expressions.
> - Any type returned as the result type of an expression will have its type
> available
>
> Greg
>
> On Feb 13, 2017, at 6:00 AM, Roman Popov via lldb-dev <
> lldb-dev@lists.llvm.org> wrote:
>
> Thats nice! But how to enable C++?:
>
> (lldb) expr --top-level --
> Enter expressions, then terminate with an empty line to evaluate:
> 1 #include 
> 2 void HOOK() { std::cout << "in hook\n"; }
> 3
>
> error: 'iostream' file not found
>
>
> 2017-02-13 16:46 GMT+03:00 Pavel Labath :
>
>> Try this for size:
>>
>>
>> $ bin/lldb /tmp/a.out
>> (lldb) target create "/tmp/a.out"
>> Current executable set to '/tmp/a.out' (x86_64).
>> (lldb) b main
>> Breakpoint 1: where = a.out`main + 4 at a.cc:6, address =
>> 0x00400531
>> (lldb) pr la
>> Process 22550 launched: '/tmp/a.out' (x86_64)
>> Process 22550 stopped
>> * thread #1, name = 'a.out', stop reason = breakpoint 1.1
>> frame #0: 0x00400531 a.out`main at a.cc:6
>>3   void (* volatile hook)();
>>4
>>5   int main() {
>> -> 6printf("before\n");
>>7if(hook) hook();
>>8printf("after\n");
>>9   }
>> (lldb) expr --top-level -- void HOOK() { (int)printf("in hook\n"); }
>> (lldb) expr hook = 
>> (void (*volatile)()) $0 = 0x77ff5030
>> (lldb) c
>> Process 22550 resuming
>> before
>> in hook
>> after
>> Process 22550 exited with status = 0 (0x)
>> (lldb)
>>
>>
>> On 13 February 2017 at 13:38, Roman Popov  wrote:
>> > Yes, it would fit. I can even insert hooks manually, like:
>> >
>> >  std::function instrumentation_hook = []{ /*dear lldb script,
>> please
>> > insert your code here*/ }
>> >
>> > instrumentation_hook(); // run instrumentation, by default does nothing.
>> >
>> >
>> > Is there an easy way to compile some code in lldb and assign to
>> > instrumentation_hook ?
>> >
>> >
>> > 2017-02-13 16:33 GMT+03:00 Pavel Labath :
>> >>
>> >> Making the code persist is easy - that's sort of what expr --top-level
>> >> does.
>> >>
>> >> The tricky part is getting your code to execute. When you evaluate
>> >> expressions interactively, we manually modify the registers (PC being
>> >> the most important one) to point to the code you want to execute. If
>> >> you want it to happen automatically at runtime, you would have to
>> >> insert a jump instruction somewhere. The problem is, that can't
>> >> usually be done without overwriting a couple of instructions of
>> >> original code, which means you then have to somehow simulate the
>> >> effects of the overwritten instructions. And there's always a danger
>> >> that you will overwrite a jump target and things will blow up when
>> >> someone tries to jump there. The way this is normally done is that you
>> >> have the compiler insert hooks into your code during compilation, that
>> >> you can then intercept if necessary. I am not sure if that would fit
>> >> your use case.
>> >>
>> >> pl
>> >>
>> >>
>> >>
>> >> On 13 February 2017 at 13:13, Roman Popov  wrote:
>> >> > Thanks Pavel, you are correct. This was the direction I thought to
>> >> > investigate, but I didnt done my homework yet.
>> >> >
>> >> > Yes, dynamic instrumentation is what I want. Looks like both lldb and
>> >> > gdb do
>> >> > not allow this directly.
>> >> >
>> >> > As GDB doc says "After execution, the compiled code is removed from
>> gdb
>> >> > and
>> >> > any new types or variables you have defined will be deleted."
>> >> >
>> >> > Do you know why it is 

Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2017-02-13 Thread Greg Clayton via lldb-dev
Clang just doesn't currently know where to look for the standard headers. Not 
sure if this is a top level code only bug or not. I know the expression parser 
can include common C headers on Darwin. Not sure if any includes work on linux. 
Try importing  and see how that goes? 

The better way to do what you want is to write a shared library, save it to 
"/tmp/liba.so" and then load it at runtime:

(lldb) process load /tmp/liba.so

This will load a shared library with all of the top level code you want into 
your current program, then you can call any functions in that shared library as 
well using expressions that you need.

If you feel you still need to use the expression parser, then a few tips on the 
expression parser when not in top level code mode:
- C++ lambda functions that don't capture anything can be cast to function 
pointer types and used as static callbacks.
- Any variable you define that is prefixed with a '$' will become a global 
variable and persist beyond your expression (assign a function callback from 
C++ lambda, and you have a callback you can now use.
- Any type you declare that is prefixed with a '$' will persist beyond that 
expression and be available for future expressions.
- Any type returned as the result type of an expression will have its type 
available

Greg

> On Feb 13, 2017, at 6:00 AM, Roman Popov via lldb-dev 
>  wrote:
> 
> Thats nice! But how to enable C++?:
> 
> (lldb) expr --top-level --
> Enter expressions, then terminate with an empty line to evaluate:
> 1 #include 
> 2 void HOOK() { std::cout << "in hook\n"; }
> 3 
> 
> error: 'iostream' file not found
> 
> 
> 2017-02-13 16:46 GMT+03:00 Pavel Labath  >:
> Try this for size:
> 
> 
> $ bin/lldb /tmp/a.out
> (lldb) target create "/tmp/a.out"
> Current executable set to '/tmp/a.out' (x86_64).
> (lldb) b main
> Breakpoint 1: where = a.out`main + 4 at a.cc:6, address = 0x00400531
> (lldb) pr la
> Process 22550 launched: '/tmp/a.out' (x86_64)
> Process 22550 stopped
> * thread #1, name = 'a.out', stop reason = breakpoint 1.1
> frame #0: 0x00400531 a.out`main at a.cc:6
>3   void (* volatile hook)();
>4
>5   int main() {
> -> 6printf("before\n");
>7if(hook) hook();
>8printf("after\n");
>9   }
> (lldb) expr --top-level -- void HOOK() { (int)printf("in hook\n"); }
> (lldb) expr hook = 
> (void (*volatile)()) $0 = 0x77ff5030
> (lldb) c
> Process 22550 resuming
> before
> in hook
> after
> Process 22550 exited with status = 0 (0x)
> (lldb)
> 
> 
> On 13 February 2017 at 13:38, Roman Popov  > wrote:
> > Yes, it would fit. I can even insert hooks manually, like:
> >
> >  std::function instrumentation_hook = []{ /*dear lldb script, please
> > insert your code here*/ }
> >
> > instrumentation_hook(); // run instrumentation, by default does nothing.
> >
> >
> > Is there an easy way to compile some code in lldb and assign to
> > instrumentation_hook ?
> >
> >
> > 2017-02-13 16:33 GMT+03:00 Pavel Labath  > >:
> >>
> >> Making the code persist is easy - that's sort of what expr --top-level
> >> does.
> >>
> >> The tricky part is getting your code to execute. When you evaluate
> >> expressions interactively, we manually modify the registers (PC being
> >> the most important one) to point to the code you want to execute. If
> >> you want it to happen automatically at runtime, you would have to
> >> insert a jump instruction somewhere. The problem is, that can't
> >> usually be done without overwriting a couple of instructions of
> >> original code, which means you then have to somehow simulate the
> >> effects of the overwritten instructions. And there's always a danger
> >> that you will overwrite a jump target and things will blow up when
> >> someone tries to jump there. The way this is normally done is that you
> >> have the compiler insert hooks into your code during compilation, that
> >> you can then intercept if necessary. I am not sure if that would fit
> >> your use case.
> >>
> >> pl
> >>
> >>
> >>
> >> On 13 February 2017 at 13:13, Roman Popov  >> > wrote:
> >> > Thanks Pavel, you are correct. This was the direction I thought to
> >> > investigate, but I didnt done my homework yet.
> >> >
> >> > Yes, dynamic instrumentation is what I want. Looks like both lldb and
> >> > gdb do
> >> > not allow this directly.
> >> >
> >> > As GDB doc says "After execution, the compiled code is removed from gdb
> >> > and
> >> > any new types or variables you have defined will be deleted."
> >> >
> >> > Do you know why it is the case? Why cannot my generated code persist?
> >> >
> >> >
> >> > Looks like technically it is possible. For example you can allocate
> >> > memory
> >> > for generated code on heap.
> >> >
> >> > GDB does not even allow me to 

Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2017-02-13 Thread Roman Popov via lldb-dev
Thats nice! But how to enable C++?:

(lldb) expr --top-level --
Enter expressions, then terminate with an empty line to evaluate:
1 #include 
2 void HOOK() { std::cout << "in hook\n"; }
3

error: 'iostream' file not found


2017-02-13 16:46 GMT+03:00 Pavel Labath :

> Try this for size:
>
>
> $ bin/lldb /tmp/a.out
> (lldb) target create "/tmp/a.out"
> Current executable set to '/tmp/a.out' (x86_64).
> (lldb) b main
> Breakpoint 1: where = a.out`main + 4 at a.cc:6, address =
> 0x00400531
> (lldb) pr la
> Process 22550 launched: '/tmp/a.out' (x86_64)
> Process 22550 stopped
> * thread #1, name = 'a.out', stop reason = breakpoint 1.1
> frame #0: 0x00400531 a.out`main at a.cc:6
>3   void (* volatile hook)();
>4
>5   int main() {
> -> 6printf("before\n");
>7if(hook) hook();
>8printf("after\n");
>9   }
> (lldb) expr --top-level -- void HOOK() { (int)printf("in hook\n"); }
> (lldb) expr hook = 
> (void (*volatile)()) $0 = 0x77ff5030
> (lldb) c
> Process 22550 resuming
> before
> in hook
> after
> Process 22550 exited with status = 0 (0x)
> (lldb)
>
>
> On 13 February 2017 at 13:38, Roman Popov  wrote:
> > Yes, it would fit. I can even insert hooks manually, like:
> >
> >  std::function instrumentation_hook = []{ /*dear lldb script,
> please
> > insert your code here*/ }
> >
> > instrumentation_hook(); // run instrumentation, by default does nothing.
> >
> >
> > Is there an easy way to compile some code in lldb and assign to
> > instrumentation_hook ?
> >
> >
> > 2017-02-13 16:33 GMT+03:00 Pavel Labath :
> >>
> >> Making the code persist is easy - that's sort of what expr --top-level
> >> does.
> >>
> >> The tricky part is getting your code to execute. When you evaluate
> >> expressions interactively, we manually modify the registers (PC being
> >> the most important one) to point to the code you want to execute. If
> >> you want it to happen automatically at runtime, you would have to
> >> insert a jump instruction somewhere. The problem is, that can't
> >> usually be done without overwriting a couple of instructions of
> >> original code, which means you then have to somehow simulate the
> >> effects of the overwritten instructions. And there's always a danger
> >> that you will overwrite a jump target and things will blow up when
> >> someone tries to jump there. The way this is normally done is that you
> >> have the compiler insert hooks into your code during compilation, that
> >> you can then intercept if necessary. I am not sure if that would fit
> >> your use case.
> >>
> >> pl
> >>
> >>
> >>
> >> On 13 February 2017 at 13:13, Roman Popov  wrote:
> >> > Thanks Pavel, you are correct. This was the direction I thought to
> >> > investigate, but I didnt done my homework yet.
> >> >
> >> > Yes, dynamic instrumentation is what I want. Looks like both lldb and
> >> > gdb do
> >> > not allow this directly.
> >> >
> >> > As GDB doc says "After execution, the compiled code is removed from
> gdb
> >> > and
> >> > any new types or variables you have defined will be deleted."
> >> >
> >> > Do you know why it is the case? Why cannot my generated code persist?
> >> >
> >> >
> >> > Looks like technically it is possible. For example you can allocate
> >> > memory
> >> > for generated code on heap.
> >> >
> >> > GDB does not even allow me to define a new function. But for data
> >> > dynamic
> >> > allocation works perfectly fine:
> >> >
> >> >
> >> > Example:
> >> >
> >> > #include 
> >> >
> >> > char message[1000] = "test message\n";
> >> >
> >> > int main() {
> >> > char *msg = message;
> >> >
> >> > for (int i = 0; i < 5; i++)
> >> > printf("%s\n", msg);
> >> >
> >> > return 0;
> >> > }
> >> >
> >> >
> >> >
> >> > gdb session:
> >> >
> >> > (gdb) break main.c:8
> >> > Breakpoint 1 at 0x400536: file main.c, line 8.
> >> > (gdb) run
> >> > Starting program: /home/ripopov/work/test_c_inject/a.out
> >> >
> >> > Breakpoint 1, main () at main.c:8
> >> > 8   for (int i = 0; i < 5; i++)
> >> > (gdb) compile code
> >> >>char *str;
> >> >>str = (char *) malloc(3);
> >> >>str[0] = 'T';
> >> >>str[1] = '\n';
> >> >>str[2] = 0;
> >> >>msg = str;
> >> >>end
> >> > (gdb) c
> >> > Continuing.
> >> > T
> >> >
> >> > T
> >> >
> >> > T
> >> >
> >> > T
> >> >
> >> > T
> >> >
> >> > [Inferior 1 (process 96445) exited normally]
> >> > (gdb)
> >> >
> >> >
> >> >
> >> >
> >> > 2017-02-13 13:56 GMT+03:00 Pavel Labath :
> >> >>
> >> >> Every time you use the "expr" command, we compile a tiny c++ code
> >> >> snippet inject it into the target process and execute it. If you type
> >> >> "log enable lldb expr" you should be able to follow how exactly that
> >> >> works. You can use pretty much any c++ construct in the expression
> >> >> including declaring variables/types:
> >> >> (lldb) expr -- char s[]="qwerty"; for(int i=0; i < sizeof s; ++i)

Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2017-02-13 Thread Pavel Labath via lldb-dev
Try this for size:


$ bin/lldb /tmp/a.out
(lldb) target create "/tmp/a.out"
Current executable set to '/tmp/a.out' (x86_64).
(lldb) b main
Breakpoint 1: where = a.out`main + 4 at a.cc:6, address = 0x00400531
(lldb) pr la
Process 22550 launched: '/tmp/a.out' (x86_64)
Process 22550 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
frame #0: 0x00400531 a.out`main at a.cc:6
   3   void (* volatile hook)();
   4
   5   int main() {
-> 6printf("before\n");
   7if(hook) hook();
   8printf("after\n");
   9   }
(lldb) expr --top-level -- void HOOK() { (int)printf("in hook\n"); }
(lldb) expr hook = 
(void (*volatile)()) $0 = 0x77ff5030
(lldb) c
Process 22550 resuming
before
in hook
after
Process 22550 exited with status = 0 (0x)
(lldb)


On 13 February 2017 at 13:38, Roman Popov  wrote:
> Yes, it would fit. I can even insert hooks manually, like:
>
>  std::function instrumentation_hook = []{ /*dear lldb script, please
> insert your code here*/ }
>
> instrumentation_hook(); // run instrumentation, by default does nothing.
>
>
> Is there an easy way to compile some code in lldb and assign to
> instrumentation_hook ?
>
>
> 2017-02-13 16:33 GMT+03:00 Pavel Labath :
>>
>> Making the code persist is easy - that's sort of what expr --top-level
>> does.
>>
>> The tricky part is getting your code to execute. When you evaluate
>> expressions interactively, we manually modify the registers (PC being
>> the most important one) to point to the code you want to execute. If
>> you want it to happen automatically at runtime, you would have to
>> insert a jump instruction somewhere. The problem is, that can't
>> usually be done without overwriting a couple of instructions of
>> original code, which means you then have to somehow simulate the
>> effects of the overwritten instructions. And there's always a danger
>> that you will overwrite a jump target and things will blow up when
>> someone tries to jump there. The way this is normally done is that you
>> have the compiler insert hooks into your code during compilation, that
>> you can then intercept if necessary. I am not sure if that would fit
>> your use case.
>>
>> pl
>>
>>
>>
>> On 13 February 2017 at 13:13, Roman Popov  wrote:
>> > Thanks Pavel, you are correct. This was the direction I thought to
>> > investigate, but I didnt done my homework yet.
>> >
>> > Yes, dynamic instrumentation is what I want. Looks like both lldb and
>> > gdb do
>> > not allow this directly.
>> >
>> > As GDB doc says "After execution, the compiled code is removed from gdb
>> > and
>> > any new types or variables you have defined will be deleted."
>> >
>> > Do you know why it is the case? Why cannot my generated code persist?
>> >
>> >
>> > Looks like technically it is possible. For example you can allocate
>> > memory
>> > for generated code on heap.
>> >
>> > GDB does not even allow me to define a new function. But for data
>> > dynamic
>> > allocation works perfectly fine:
>> >
>> >
>> > Example:
>> >
>> > #include 
>> >
>> > char message[1000] = "test message\n";
>> >
>> > int main() {
>> > char *msg = message;
>> >
>> > for (int i = 0; i < 5; i++)
>> > printf("%s\n", msg);
>> >
>> > return 0;
>> > }
>> >
>> >
>> >
>> > gdb session:
>> >
>> > (gdb) break main.c:8
>> > Breakpoint 1 at 0x400536: file main.c, line 8.
>> > (gdb) run
>> > Starting program: /home/ripopov/work/test_c_inject/a.out
>> >
>> > Breakpoint 1, main () at main.c:8
>> > 8   for (int i = 0; i < 5; i++)
>> > (gdb) compile code
>> >>char *str;
>> >>str = (char *) malloc(3);
>> >>str[0] = 'T';
>> >>str[1] = '\n';
>> >>str[2] = 0;
>> >>msg = str;
>> >>end
>> > (gdb) c
>> > Continuing.
>> > T
>> >
>> > T
>> >
>> > T
>> >
>> > T
>> >
>> > T
>> >
>> > [Inferior 1 (process 96445) exited normally]
>> > (gdb)
>> >
>> >
>> >
>> >
>> > 2017-02-13 13:56 GMT+03:00 Pavel Labath :
>> >>
>> >> Every time you use the "expr" command, we compile a tiny c++ code
>> >> snippet inject it into the target process and execute it. If you type
>> >> "log enable lldb expr" you should be able to follow how exactly that
>> >> works. You can use pretty much any c++ construct in the expression
>> >> including declaring variables/types:
>> >> (lldb) expr -- char s[]="qwerty"; for(int i=0; i < sizeof s; ++i)
>> >> printf("%d: %c\n", i, s[i]);
>> >> 0: q
>> >> 1: w
>> >> 2: e
>> >> 3: r
>> >> 4: t
>> >> 5: y
>> >> 6:
>> >>
>> >>
>> >> So, if your question is "do we support compiling code and running it
>> >> in the debugged process", then the answer is yes. If you want
>> >> something that would automatically intercept some function to execute
>> >> your code while the process is running (some kind of dynamic
>> >> instrumentation), then the answer is no. (But I don't see any mention
>> >> of that on the gdb page you quoted either).
>> >>
>> >> cheers,
>> >> pavel
>> >>
>> >> On 12 February 

Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2017-02-13 Thread Roman Popov via lldb-dev
Yes, it would fit. I can even insert hooks manually, like:

 std::function instrumentation_hook = []{ /*dear lldb script,
please insert your code here*/ }

instrumentation_hook(); // run instrumentation, by default does nothing.


Is there an easy way to compile some code in lldb and assign to
instrumentation_hook ?


2017-02-13 16:33 GMT+03:00 Pavel Labath :

> Making the code persist is easy - that's sort of what expr --top-level
> does.
>
> The tricky part is getting your code to execute. When you evaluate
> expressions interactively, we manually modify the registers (PC being
> the most important one) to point to the code you want to execute. If
> you want it to happen automatically at runtime, you would have to
> insert a jump instruction somewhere. The problem is, that can't
> usually be done without overwriting a couple of instructions of
> original code, which means you then have to somehow simulate the
> effects of the overwritten instructions. And there's always a danger
> that you will overwrite a jump target and things will blow up when
> someone tries to jump there. The way this is normally done is that you
> have the compiler insert hooks into your code during compilation, that
> you can then intercept if necessary. I am not sure if that would fit
> your use case.
>
> pl
>
>
>
> On 13 February 2017 at 13:13, Roman Popov  wrote:
> > Thanks Pavel, you are correct. This was the direction I thought to
> > investigate, but I didnt done my homework yet.
> >
> > Yes, dynamic instrumentation is what I want. Looks like both lldb and
> gdb do
> > not allow this directly.
> >
> > As GDB doc says "After execution, the compiled code is removed from gdb
> and
> > any new types or variables you have defined will be deleted."
> >
> > Do you know why it is the case? Why cannot my generated code persist?
> >
> >
> > Looks like technically it is possible. For example you can allocate
> memory
> > for generated code on heap.
> >
> > GDB does not even allow me to define a new function. But for data dynamic
> > allocation works perfectly fine:
> >
> >
> > Example:
> >
> > #include 
> >
> > char message[1000] = "test message\n";
> >
> > int main() {
> > char *msg = message;
> >
> > for (int i = 0; i < 5; i++)
> > printf("%s\n", msg);
> >
> > return 0;
> > }
> >
> >
> >
> > gdb session:
> >
> > (gdb) break main.c:8
> > Breakpoint 1 at 0x400536: file main.c, line 8.
> > (gdb) run
> > Starting program: /home/ripopov/work/test_c_inject/a.out
> >
> > Breakpoint 1, main () at main.c:8
> > 8   for (int i = 0; i < 5; i++)
> > (gdb) compile code
> >>char *str;
> >>str = (char *) malloc(3);
> >>str[0] = 'T';
> >>str[1] = '\n';
> >>str[2] = 0;
> >>msg = str;
> >>end
> > (gdb) c
> > Continuing.
> > T
> >
> > T
> >
> > T
> >
> > T
> >
> > T
> >
> > [Inferior 1 (process 96445) exited normally]
> > (gdb)
> >
> >
> >
> >
> > 2017-02-13 13:56 GMT+03:00 Pavel Labath :
> >>
> >> Every time you use the "expr" command, we compile a tiny c++ code
> >> snippet inject it into the target process and execute it. If you type
> >> "log enable lldb expr" you should be able to follow how exactly that
> >> works. You can use pretty much any c++ construct in the expression
> >> including declaring variables/types:
> >> (lldb) expr -- char s[]="qwerty"; for(int i=0; i < sizeof s; ++i)
> >> printf("%d: %c\n", i, s[i]);
> >> 0: q
> >> 1: w
> >> 2: e
> >> 3: r
> >> 4: t
> >> 5: y
> >> 6:
> >>
> >>
> >> So, if your question is "do we support compiling code and running it
> >> in the debugged process", then the answer is yes. If you want
> >> something that would automatically intercept some function to execute
> >> your code while the process is running (some kind of dynamic
> >> instrumentation), then the answer is no. (But I don't see any mention
> >> of that on the gdb page you quoted either).
> >>
> >> cheers,
> >> pavel
> >>
> >> On 12 February 2017 at 18:34, Roman Popov via lldb-dev
> >>  wrote:
> >> > Hello Benjamin , all
> >> >
> >> >>>I recently started using lldb to write a basic instrumentation tool
> for
> >> >>>tracking the values of variables at various code-points in a program.
> >> >
> >> > I have the same problem of tracing some variables and debugging
> >> > application
> >> > post-mortem. Without knowing about your experience I've started
> walking
> >> > same
> >> > path and encountered same problem. In my case inserting an empty
> >> > callback
> >> > slows-down application by 100x. This is not acceptable for me, because
> >> > instead of minutes I got hours of runtime.
> >> >
> >> > Did you found any faster solution?
> >> >
> >> > My current plan is to solve it with code injection: I plan to find
> >> > pointers
> >> > to interesting values using debugger scripting and then inject code to
> >> > trace
> >> > them.
> >> >
> >> > Does LLDB supports code injection ? I've found information only about
> >> > gdb
> >> 

Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2017-02-13 Thread Pavel Labath via lldb-dev
Making the code persist is easy - that's sort of what expr --top-level does.

The tricky part is getting your code to execute. When you evaluate
expressions interactively, we manually modify the registers (PC being
the most important one) to point to the code you want to execute. If
you want it to happen automatically at runtime, you would have to
insert a jump instruction somewhere. The problem is, that can't
usually be done without overwriting a couple of instructions of
original code, which means you then have to somehow simulate the
effects of the overwritten instructions. And there's always a danger
that you will overwrite a jump target and things will blow up when
someone tries to jump there. The way this is normally done is that you
have the compiler insert hooks into your code during compilation, that
you can then intercept if necessary. I am not sure if that would fit
your use case.

pl



On 13 February 2017 at 13:13, Roman Popov  wrote:
> Thanks Pavel, you are correct. This was the direction I thought to
> investigate, but I didnt done my homework yet.
>
> Yes, dynamic instrumentation is what I want. Looks like both lldb and gdb do
> not allow this directly.
>
> As GDB doc says "After execution, the compiled code is removed from gdb and
> any new types or variables you have defined will be deleted."
>
> Do you know why it is the case? Why cannot my generated code persist?
>
>
> Looks like technically it is possible. For example you can allocate memory
> for generated code on heap.
>
> GDB does not even allow me to define a new function. But for data dynamic
> allocation works perfectly fine:
>
>
> Example:
>
> #include 
>
> char message[1000] = "test message\n";
>
> int main() {
> char *msg = message;
>
> for (int i = 0; i < 5; i++)
> printf("%s\n", msg);
>
> return 0;
> }
>
>
>
> gdb session:
>
> (gdb) break main.c:8
> Breakpoint 1 at 0x400536: file main.c, line 8.
> (gdb) run
> Starting program: /home/ripopov/work/test_c_inject/a.out
>
> Breakpoint 1, main () at main.c:8
> 8   for (int i = 0; i < 5; i++)
> (gdb) compile code
>>char *str;
>>str = (char *) malloc(3);
>>str[0] = 'T';
>>str[1] = '\n';
>>str[2] = 0;
>>msg = str;
>>end
> (gdb) c
> Continuing.
> T
>
> T
>
> T
>
> T
>
> T
>
> [Inferior 1 (process 96445) exited normally]
> (gdb)
>
>
>
>
> 2017-02-13 13:56 GMT+03:00 Pavel Labath :
>>
>> Every time you use the "expr" command, we compile a tiny c++ code
>> snippet inject it into the target process and execute it. If you type
>> "log enable lldb expr" you should be able to follow how exactly that
>> works. You can use pretty much any c++ construct in the expression
>> including declaring variables/types:
>> (lldb) expr -- char s[]="qwerty"; for(int i=0; i < sizeof s; ++i)
>> printf("%d: %c\n", i, s[i]);
>> 0: q
>> 1: w
>> 2: e
>> 3: r
>> 4: t
>> 5: y
>> 6:
>>
>>
>> So, if your question is "do we support compiling code and running it
>> in the debugged process", then the answer is yes. If you want
>> something that would automatically intercept some function to execute
>> your code while the process is running (some kind of dynamic
>> instrumentation), then the answer is no. (But I don't see any mention
>> of that on the gdb page you quoted either).
>>
>> cheers,
>> pavel
>>
>> On 12 February 2017 at 18:34, Roman Popov via lldb-dev
>>  wrote:
>> > Hello Benjamin , all
>> >
>> >>>I recently started using lldb to write a basic instrumentation tool for
>> >>>tracking the values of variables at various code-points in a program.
>> >
>> > I have the same problem of tracing some variables and debugging
>> > application
>> > post-mortem. Without knowing about your experience I've started walking
>> > same
>> > path and encountered same problem. In my case inserting an empty
>> > callback
>> > slows-down application by 100x. This is not acceptable for me, because
>> > instead of minutes I got hours of runtime.
>> >
>> > Did you found any faster solution?
>> >
>> > My current plan is to solve it with code injection: I plan to find
>> > pointers
>> > to interesting values using debugger scripting and then inject code to
>> > trace
>> > them.
>> >
>> > Does LLDB supports code injection ? I've found information only about
>> > gdb
>> >
>> > https://sourceware.org/gdb/onlinedocs/gdb/Compiling-and-Injecting-Code.html
>> > but not about lldb
>> >
>> >
>> > -Roman
>> >
>> >
>> > ___
>> > lldb-dev mailing list
>> > lldb-dev@lists.llvm.org
>> > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>> >
>
>
___
lldb-dev mailing list
lldb-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev


Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2017-02-13 Thread Pavel Labath via lldb-dev
Every time you use the "expr" command, we compile a tiny c++ code
snippet inject it into the target process and execute it. If you type
"log enable lldb expr" you should be able to follow how exactly that
works. You can use pretty much any c++ construct in the expression
including declaring variables/types:
(lldb) expr -- char s[]="qwerty"; for(int i=0; i < sizeof s; ++i)
printf("%d: %c\n", i, s[i]);
0: q
1: w
2: e
3: r
4: t
5: y
6:


So, if your question is "do we support compiling code and running it
in the debugged process", then the answer is yes. If you want
something that would automatically intercept some function to execute
your code while the process is running (some kind of dynamic
instrumentation), then the answer is no. (But I don't see any mention
of that on the gdb page you quoted either).

cheers,
pavel

On 12 February 2017 at 18:34, Roman Popov via lldb-dev
 wrote:
> Hello Benjamin , all
>
>>>I recently started using lldb to write a basic instrumentation tool for
>>>tracking the values of variables at various code-points in a program.
>
> I have the same problem of tracing some variables and debugging application
> post-mortem. Without knowing about your experience I've started walking same
> path and encountered same problem. In my case inserting an empty callback
> slows-down application by 100x. This is not acceptable for me, because
> instead of minutes I got hours of runtime.
>
> Did you found any faster solution?
>
> My current plan is to solve it with code injection: I plan to find pointers
> to interesting values using debugger scripting and then inject code to trace
> them.
>
> Does LLDB supports code injection ? I've found information only about gdb
> https://sourceware.org/gdb/onlinedocs/gdb/Compiling-and-Injecting-Code.html
> but not about lldb
>
>
> -Roman
>
>
> ___
> lldb-dev mailing list
> lldb-dev@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev
>
___
lldb-dev mailing list
lldb-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev


Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2017-02-12 Thread Roman Popov via lldb-dev
Hello Benjamin , all

>>I recently started using lldb to write a basic instrumentation tool for
>>tracking the values of variables at various code-points in a program.

I have the same problem of tracing some variables and debugging
application post-mortem. Without knowing about your experience I've
started walking same path and encountered same problem. In my case
inserting an empty callback slows-down application by 100x. This is
not acceptable for me, because instead of minutes I got hours of
runtime.

Did you found any faster solution?

My current plan is to solve it with code injection: I plan to find
pointers to interesting values using debugger scripting and then
inject code to trace them.

Does LLDB supports code injection ? I've found information only about
gdb https://sourceware.org/gdb/onlinedocs/gdb/Compiling-and-Injecting-Code.html
but not about lldb


-Roman
___
lldb-dev mailing list
lldb-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev


Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2016-08-17 Thread Pavel Labath via lldb-dev
Hello Benjamin, all,

the lldb-server implementation in linux works exactly the same way as
debugserver does on osx -- it runs out of process and uses sockets to
communicate with the client. The socketpair() optimization that Jim is
talking about is not enabled there yet - I want to do some benchmarks
first to make sure it really helps. Feel free to try it out if you
want, I'd be very interested in hearing the results (the relevant
commit is r278524). However, I doubt it will make enough difference to
make your use case work.

Moving the debugging code into the same process could easily make
things an order of magnitude faster and it _might_ be enough for your
purposes, but it's an extremely non-trivial task. I think doing that
would be a great idea, but I would expect a serious commitment to
maintaining and testing that path from whoever wanted to do that.

cheers,
pl


On 16 August 2016 at 21:43, Benjamin Dicken via lldb-dev
 wrote:
>
>
> On Tue, Aug 16, 2016 at 11:06 AM, Jim Ingham  wrote:
>>
>>
>> > On Aug 16, 2016, at 10:42 AM, Benjamin Dicken
>> >  wrote:
>> >
>> > Thanks for the quick reply.
>> >
>> > > Are you sure the actual handling of the breakpoint & callback in lldb
>> > > is what is taking most of the time?
>> >
>> > I'm not positive. I did collect some callgrind profiles to take a look
>> > at where most of the time is being spent, but i'm not very familiar with
>> > lldb internals so the results were hard to interpret. I did notice that
>> > there was a lot of packet/network business when using lldb to profile a
>> > program (which I assumed was communication between my program and
>> > lldb-server). I was not sure how this effected the performance, so perhaps
>> > this is the real bottleneck.
>>
>> I would be pretty surprised if it was not.  We had some bugs in breakpoint
>> handling - mostly related to having very very many breakpoints.  But other
>> than that the dispatching of the breakpoint StopInfo is a pretty simple,
>> straight forward bit of work.
>>
>> >
>> > > Greg just switched to using a unix-domain socket for this
>> > > communication for platforms that support it.  This speeds up the packet
>> > > traffic side of things.
>> >
>> > In what version of lldb was this introduced? I'm running 3.7.1. I'm also
>> > on ubuntu 14.04, is that a supported platform?
>>
>> It is just in TOT lldb, he just added it last week.  It is currently only
>> turned on for OS X.
>
>
> Good to know, thanks.
>>
>>
>> >
>> > > One of the original motivations of having lldb-server be based on lldb
>> > > classes - as opposed to the MacOS X version of debugserver which is an
>> > > independent construct - was that you could re-use the server code to 
>> > > create
>> > > an in-process Process plugin, eliminating a lot of this traffic & context
>> > > switching when you needed maximum speed.
>> >
>> > That sounds very interesting. Is there an example of this implementation
>> > you could point me to?
>> >
>>
>> FreeBSB & Windows still have native Process plugins.  But they aren't used
>> for the lldb-server implementation so far as I can tell (I've mostly worked
>> on the OS X side.)  I think this was more of a design intent that hasn't
>> actually been used anywhere yet.  But the Linux/Android folks will know
>> better.
>
>
> If any of the Linux/Andriod folks do know, please get in touch with me.
> Thanks,
>
>>
>> Jim
>>
>>
>> >
>> >
>> > On Tue, Aug 16, 2016 at 10:20 AM, Jim Ingham  wrote:
>> > Are you sure the actual handling of the breakpoint & callback in lldb is
>> > what is taking most of the time?  The last time we looked at this, the
>> > majority of the work was in communicating with debugserver to get the stop
>> > notification and restart.  Note, besides all the packet code, this involves
>> > context switches from process->lldbserver->lldb and back, which is also
>> > pretty expensive.
>> >
>> > Greg just switched to using a unix-domain socket for this communication
>> > for platforms that support it.  This speeds up the packet traffic side of
>> > things.
>> >
>> > One of the original motivations of having lldb-server be based on lldb
>> > classes - as opposed to the MacOS X version of debugserver which is an
>> > independent construct - was that you could re-use the server code to create
>> > an in-process Process plugin, eliminating a lot of this traffic & context
>> > switching when you needed maximum speed.  The original Mac OS X lldb port
>> > actually had a process plugin wholly in-process with lldb as well as the
>> > debugserver based one, but there wasn't enough motivation to justify
>> > maintaining the two different implementations of the same code.  I don't
>> > know whether the Linux port takes advantage of this possibility, however.
>> > That would be something to look into, however.
>> >
>> > Once we actually figure out about the stop, figuring out the breakpoint
>> > and getting to 

Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2016-08-16 Thread Benjamin Dicken via lldb-dev
On Tue, Aug 16, 2016 at 11:06 AM, Jim Ingham  wrote:

>
> > On Aug 16, 2016, at 10:42 AM, Benjamin Dicken <
> bddic...@datawareventures.com> wrote:
> >
> > Thanks for the quick reply.
> >
> > > Are you sure the actual handling of the breakpoint & callback in lldb
> is what is taking most of the time?
> >
> > I'm not positive. I did collect some callgrind profiles to take a look
> at where most of the time is being spent, but i'm not very familiar with
> lldb internals so the results were hard to interpret. I did notice that
> there was a lot of packet/network business when using lldb to profile a
> program (which I assumed was communication between my program and
> lldb-server). I was not sure how this effected the performance, so perhaps
> this is the real bottleneck.
>
> I would be pretty surprised if it was not.  We had some bugs in breakpoint
> handling - mostly related to having very very many breakpoints.  But other
> than that the dispatching of the breakpoint StopInfo is a pretty simple,
> straight forward bit of work.
>
> >
> > > Greg just switched to using a unix-domain socket for this
> communication for platforms that support it.  This speeds up the packet
> traffic side of things.
> >
> > In what version of lldb was this introduced? I'm running 3.7.1. I'm also
> on ubuntu 14.04, is that a supported platform?
>
> It is just in TOT lldb, he just added it last week.  It is currently only
> turned on for OS X.
>

Good to know, thanks.

>
> >
> > > One of the original motivations of having lldb-server be based on lldb
> classes - as opposed to the MacOS X version of debugserver which is an
> independent construct - was that you could re-use the server code to create
> an in-process Process plugin, eliminating a lot of this traffic & context
> switching when you needed maximum speed.
> >
> > That sounds very interesting. Is there an example of this implementation
> you could point me to?
> >
>
> FreeBSB & Windows still have native Process plugins.  But they aren't used
> for the lldb-server implementation so far as I can tell (I've mostly worked
> on the OS X side.)  I think this was more of a design intent that hasn't
> actually been used anywhere yet.  But the Linux/Android folks will know
> better.
>

If any of the Linux/Andriod folks do know, please get in touch with me.
Thanks,


> Jim
>
>
> >
> >
> > On Tue, Aug 16, 2016 at 10:20 AM, Jim Ingham  wrote:
> > Are you sure the actual handling of the breakpoint & callback in lldb is
> what is taking most of the time?  The last time we looked at this, the
> majority of the work was in communicating with debugserver to get the stop
> notification and restart.  Note, besides all the packet code, this involves
> context switches from process->lldbserver->lldb and back, which is also
> pretty expensive.
> >
> > Greg just switched to using a unix-domain socket for this communication
> for platforms that support it.  This speeds up the packet traffic side of
> things.
> >
> > One of the original motivations of having lldb-server be based on lldb
> classes - as opposed to the MacOS X version of debugserver which is an
> independent construct - was that you could re-use the server code to create
> an in-process Process plugin, eliminating a lot of this traffic & context
> switching when you needed maximum speed.  The original Mac OS X lldb port
> actually had a process plugin wholly in-process with lldb as well as the
> debugserver based one, but there wasn't enough motivation to justify
> maintaining the two different implementations of the same code.  I don't
> know whether the Linux port takes advantage of this possibility, however.
> That would be something to look into, however.
> >
> > Once we actually figure out about the stop, figuring out the breakpoint
> and getting to its callback is pretty simple...  I doubt making "lighter
> weight breakpoints" in particular will recover the performance you need,
> though if your sampling turns up some inefficient algorithms have crept in,
> it would be great to fix that.
> >
> > Another option we've toyed with on and off is something like the gdb
> "tracepoints" were you can upload instructions to perform "experiments"
> when a breakpoint is hit to the lldb-server instance.  The work to perform
> the experiment and the results would all be kept in the lldb-server
> instance till a real breakpoint is hit, at which point lldb can download
> all the results and present them to the user.  This would eliminate some of
> the context-switches and packet traffic while you were running in the hot
> parts of your code.  This is a decent chunk of work, however.
> >
> > Jim
> >
> >
> > > On Aug 16, 2016, at 9:57 AM, Benjamin Dicken via lldb-dev <
> lldb-dev@lists.llvm.org> wrote:
> > >
> > > I recently started using lldb to write a basic instrumentation tool
> for tracking the values of variables at various code-points in a program.
> I've been working with lldb for less than two 

Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2016-08-16 Thread Benjamin Dicken via lldb-dev
Thanks for the quick reply.

> Are you sure the actual handling of the breakpoint & callback in lldb is
what is taking most of the time?

I'm not positive. I did collect some callgrind profiles to take a look at
where most of the time is being spent, but i'm not very familiar with lldb
internals so the results were hard to interpret. I did notice that there
was a lot of packet/network business when using lldb to profile a program
(which I assumed was communication between my program and lldb-server). I
was not sure how this effected the performance, so perhaps this is the real
bottleneck.

> Greg just switched to using a unix-domain socket for this communication
for platforms that support it.  This speeds up the packet traffic side of
things.

In what version of lldb was this introduced? I'm running 3.7.1. I'm also on
ubuntu 14.04, is that a supported platform?

> One of the original motivations of having lldb-server be based on lldb
classes - as opposed to the MacOS X version of debugserver which is an
independent construct - was that you could re-use the server code to create
an in-process Process plugin, eliminating a lot of this traffic & context
switching when you needed maximum speed.

That sounds very interesting. Is there an example of this implementation
you could point me to?



On Tue, Aug 16, 2016 at 10:20 AM, Jim Ingham  wrote:

> Are you sure the actual handling of the breakpoint & callback in lldb is
> what is taking most of the time?  The last time we looked at this, the
> majority of the work was in communicating with debugserver to get the stop
> notification and restart.  Note, besides all the packet code, this involves
> context switches from process->lldbserver->lldb and back, which is also
> pretty expensive.
>
> Greg just switched to using a unix-domain socket for this communication
> for platforms that support it.  This speeds up the packet traffic side of
> things.
>
> One of the original motivations of having lldb-server be based on lldb
> classes - as opposed to the MacOS X version of debugserver which is an
> independent construct - was that you could re-use the server code to create
> an in-process Process plugin, eliminating a lot of this traffic & context
> switching when you needed maximum speed.  The original Mac OS X lldb port
> actually had a process plugin wholly in-process with lldb as well as the
> debugserver based one, but there wasn't enough motivation to justify
> maintaining the two different implementations of the same code.  I don't
> know whether the Linux port takes advantage of this possibility, however.
> That would be something to look into, however.
>
> Once we actually figure out about the stop, figuring out the breakpoint
> and getting to its callback is pretty simple...  I doubt making "lighter
> weight breakpoints" in particular will recover the performance you need,
> though if your sampling turns up some inefficient algorithms have crept in,
> it would be great to fix that.
>
> Another option we've toyed with on and off is something like the gdb
> "tracepoints" were you can upload instructions to perform "experiments"
> when a breakpoint is hit to the lldb-server instance.  The work to perform
> the experiment and the results would all be kept in the lldb-server
> instance till a real breakpoint is hit, at which point lldb can download
> all the results and present them to the user.  This would eliminate some of
> the context-switches and packet traffic while you were running in the hot
> parts of your code.  This is a decent chunk of work, however.
>
> Jim
>
>
> > On Aug 16, 2016, at 9:57 AM, Benjamin Dicken via lldb-dev <
> lldb-dev@lists.llvm.org> wrote:
> >
> > I recently started using lldb to write a basic instrumentation tool for
> tracking the values of variables at various code-points in a program. I've
> been working with lldb for less than two weeks, so I am pretty new. Though,
> I have used and written llvm passes in the past, so I'm familiar with the
> clang/llvm/lldb ecosystem.
> >
> > I have a very early prototype of the tool up and running, using the C++
> API. The user can specify either an executable to run or an already-running
> PID to attach to. The user also supplies a file+line_number at which a
> breakpoint (with a callback) is placed. For testing/prototyping purposes,
> the breakpoint callback just increments a counter and then immediately
> returns false. Eventually, more interesting things will happen in this
> callback.
> >
> > I've noticed that just the action of hitting a breakpoint and invoking
> the callback is very expensive. I did some instruction-count collection by
> running this lldb tool on a simple test program, and placing the
> breakpoint+callback at different points in the program, causing it to get
> triggered different amounts of times. I used `perf stat -e instructions
> ...` to gather instruction exec counts for each run. After doing a little
> math, it appears that I'm incurring 1.0 - 

Re: [lldb-dev] Breakpoint + callback performance ... Can it be faster?

2016-08-16 Thread Jim Ingham via lldb-dev
Are you sure the actual handling of the breakpoint & callback in lldb is what 
is taking most of the time?  The last time we looked at this, the majority of 
the work was in communicating with debugserver to get the stop notification and 
restart.  Note, besides all the packet code, this involves context switches 
from process->lldbserver->lldb and back, which is also pretty expensive.  

Greg just switched to using a unix-domain socket for this communication for 
platforms that support it.  This speeds up the packet traffic side of things.  

One of the original motivations of having lldb-server be based on lldb classes 
- as opposed to the MacOS X version of debugserver which is an independent 
construct - was that you could re-use the server code to create an in-process 
Process plugin, eliminating a lot of this traffic & context switching when you 
needed maximum speed.  The original Mac OS X lldb port actually had a process 
plugin wholly in-process with lldb as well as the debugserver based one, but 
there wasn't enough motivation to justify maintaining the two different 
implementations of the same code.  I don't know whether the Linux port takes 
advantage of this possibility, however.  That would be something to look into, 
however.

Once we actually figure out about the stop, figuring out the breakpoint and 
getting to its callback is pretty simple...  I doubt making "lighter weight 
breakpoints" in particular will recover the performance you need, though if 
your sampling turns up some inefficient algorithms have crept in, it would be 
great to fix that.

Another option we've toyed with on and off is something like the gdb 
"tracepoints" were you can upload instructions to perform "experiments" when a 
breakpoint is hit to the lldb-server instance.  The work to perform the 
experiment and the results would all be kept in the lldb-server instance till a 
real breakpoint is hit, at which point lldb can download all the results and 
present them to the user.  This would eliminate some of the context-switches 
and packet traffic while you were running in the hot parts of your code.  This 
is a decent chunk of work, however.

Jim


> On Aug 16, 2016, at 9:57 AM, Benjamin Dicken via lldb-dev 
>  wrote:
> 
> I recently started using lldb to write a basic instrumentation tool for 
> tracking the values of variables at various code-points in a program. I've 
> been working with lldb for less than two weeks, so I am pretty new. Though, I 
> have used and written llvm passes in the past, so I'm familiar with the 
> clang/llvm/lldb ecosystem.
> 
> I have a very early prototype of the tool up and running, using the C++ API. 
> The user can specify either an executable to run or an already-running PID to 
> attach to. The user also supplies a file+line_number at which a breakpoint 
> (with a callback) is placed. For testing/prototyping purposes, the breakpoint 
> callback just increments a counter and then immediately returns false. 
> Eventually, more interesting things will happen in this callback.
> 
> I've noticed that just the action of hitting a breakpoint and invoking the 
> callback is very expensive. I did some instruction-count collection by 
> running this lldb tool on a simple test program, and placing the 
> breakpoint+callback at different points in the program, causing it to get 
> triggered different amounts of times. I used `perf stat -e instructions ...` 
> to gather instruction exec counts for each run. After doing a little math, it 
> appears that I'm incurring 1.0 - 1.1 million instruction execs per breakpoint.
> 
> This amount of slowdown is prohibitively expensive for my needs, because I 
> want to place callbacks in hot portions of the "inferior" program.
> 
> Is there a way to make this faster? Is it possible to create "lighter-weight" 
> breakpoints? I really like the lldb API (though the documentation is lacking 
> in some places), but if this performance hit can't be mitigated, it may be 
> unusable for me.
> 
> For reference, this is the callback function:
> 
> ``` 
> static int cb_count = 0;
> bool SimpleCallback (
> void *baton,  
> lldb::SBProcess ,
> lldb::SBThread ,
> lldb::SBBreakpointLocation ) {
>   //TODO: Eventually do more interesting things...
>   cb_count++; 
>   return false;
> }
> ```
> 
> And here is how I set it up to be called back:
> 
> ```
> lldb::SBBreakpoint bp1 = 
> debugger_data->target.BreakpointCreateByLocation(file_name, line_no);
> if (!bp1.IsValid()) std::cerr << "invalid breakpoint";
> bp1.SetCallback(SimpleCallback, 0);
> ```
> 
> -Benjamin
> ___
> lldb-dev mailing list
> lldb-dev@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

___
lldb-dev mailing list
lldb-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev


[lldb-dev] Breakpoint + callback performance ... Can it be faster?

2016-08-16 Thread Benjamin Dicken via lldb-dev
I recently started using lldb to write a basic instrumentation tool for
tracking the values of variables at various code-points in a program. I've
been working with lldb for less than two weeks, so I am pretty new. Though,
I have used and written llvm passes in the past, so I'm familiar with the
clang/llvm/lldb ecosystem.

I have a very early prototype of the tool up and running, using the C++
API. The user can specify either an executable to run or an already-running
PID to attach to. The user also supplies a file+line_number at which a
breakpoint (with a callback) is placed. For testing/prototyping purposes,
the breakpoint callback just increments a counter and then immediately
returns false. Eventually, more interesting things will happen in this
callback.

I've noticed that just the action of hitting a breakpoint and invoking the
callback is very expensive. I did some instruction-count collection by
running this lldb tool on a simple test program, and placing the
breakpoint+callback at different points in the program, causing it to get
triggered different amounts of times. I used `perf stat -e instructions
...` to gather instruction exec counts for each run. After doing a little
math, it appears that I'm incurring 1.0 - 1.1 million instruction execs per
breakpoint.

This amount of slowdown is prohibitively expensive for my needs, because I
want to place callbacks in hot portions of the "inferior" program.

Is there a way to make this faster? Is it possible to create
"lighter-weight" breakpoints? I really like the lldb API (though the
documentation is lacking in some places), but if this performance hit can't
be mitigated, it may be unusable for me.

For reference, this is the callback function:

```
static int cb_count = 0;
bool SimpleCallback (
void *baton,
lldb::SBProcess ,
lldb::SBThread ,
lldb::SBBreakpointLocation ) {
  //TODO: Eventually do more interesting things...
  cb_count++;
  return false;
}
```

And here is how I set it up to be called back:

```
lldb::SBBreakpoint bp1 =
debugger_data->target.BreakpointCreateByLocation(file_name, line_no);
if (!bp1.IsValid()) std::cerr << "invalid breakpoint";
bp1.SetCallback(SimpleCallback, 0);
```

-Benjamin
___
lldb-dev mailing list
lldb-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev