3

I'm trying to get a better grasp of LLDB and am currently stuck trying to call a locally defined function (using LLDB's expr) while debugging some code. For the sake of simplicity, lets consider this toy code:

testing_lldb.c:

unsigned long factorial(unsigned input) {
    unsigned long ret_val = 0;

    if (input == 0)
        ret_val = 1;
    else
        ret_val = input * (factorial(input-1));

    return ret_val; 
}

I compile it like this:

$ clang -g -Weverything -c lldb_test.c

and then run LLDB by typing:

$ lldb testing_lldb.o

In my LLDB session, I'd like to be able to call factorial(). My first attempt:

(lldb) expr unsigned long i = factorial(i);
error: 'factorial' has unknown return type;  
cast the call to its declared return type

The error message includes a clear hint, so I try again:

(lldb) expr unsigned long i = (unsigned long)factorial(i);
error: warning: function 'factorial' has internal linkage but is not defined
note: used here
error: Can't run the expression locally: Interpreter doesn't handle one of the expression's opcodes

Fine, I try to define factorial() manually by following the answer for this SO question:

(lldb) expr typedef unsigned long (*$factorial_type)(unsigned)
(lldb) expr $factorial_type $factorial_function = ($factorial_type)0x0000000000000000
(lldb) expr unsigned long i = (unsigned long)factorial(i);
error: warning: function 'factorial' has internal linkage but is not defined
note: used here
error: Can't run the expression locally: Interpreter doesn't handle one of the expression's opcodes

And this gives me exactly same error as above. I double checked the starting address of factorial() by running:

(lldb) image lookup -Avi -n factorial 

Question

Given testing_lldb.c, what's required to be able to use factorial() in expressions in LLDB?

Some details regarding the enviroment:

$ uname -r
3.16.0-4-amd64
$ lldb -v
lldb version 3.4.2 ( revision )
$ clang -v
Debian clang version 3.4.2-14 (tags/RELEASE_34/dot2-final) (based on LLVM 3.4.2)
Target: x86_64-pc-linux-gnu
4

1 回答 1

4

如果您正在调试实时进程,则只能使用表达式解析器来评估运行函数的表达式。您不仅没有调试实时进程,而且还在调试 .o 文件——它没有完全链接——因此它永远无法运行。lldb 可以检查 .o 文件,转储符号表和类似的东西,但并非一切都能正常工作。

您想在“testing_lldb.c”中添加一个小 main 函数,并构建一个可运行的程序(删除 -c 标志。)然后在 main 上设置一个断点:

(lldb) break set -n main

运行程序

(lldb) run

然后当你遇到断点时,尝试调用你的函数。

于 2015-06-15T21:57:18.967 回答