Thats nice! But how to enable C++?: (lldb) expr --top-level -- Enter expressions, then terminate with an empty line to evaluate: 1 #include <iostream> 2 void HOOK() { std::cout << "in hook\n"; } 3
error: 'iostream' file not found 2017-02-13 16:46 GMT+03:00 Pavel Labath <lab...@google.com>: > 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 = > 0x0000000000400531 > (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: 0x0000000000400531 a.out`main at a.cc:6 > 3 void (* volatile hook)(); > 4 > 5 int main() { > -> 6 printf("before\n"); > 7 if(hook) hook(); > 8 printf("after\n"); > 9 } > (lldb) expr --top-level -- void HOOK() { (int)printf("in hook\n"); } > (lldb) expr hook = &HOOK > (void (*volatile)()) $0 = 0x00007ffff7ff5030 > (lldb) c > Process 22550 resuming > before > in hook > after > Process 22550 exited with status = 0 (0x00000000) > (lldb) > > > On 13 February 2017 at 13:38, Roman Popov <ripo...@gmail.com> wrote: > > Yes, it would fit. I can even insert hooks manually, like: > > > > std::function<void()> 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 <lab...@google.com>: > >> > >> 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 <ripo...@gmail.com> 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 <stdio.h> > >> > > >> > 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 <lab...@google.com>: > >> >> > >> >> 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 > >> >> <lldb-dev@lists.llvm.org> 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