[lldb-dev] Calling const char* functions from within lldb

Greg Clayton gclayton at apple.com
Tue Mar 5 09:55:13 PST 2013


On Mar 5, 2013, at 8:48 AM, Carlo Kok <ck at remobjects.com> wrote:

> I want to do a msgSend so first I need a selector (Which needs an NSString/CFString) so my first step was:
> 
> FindSymbolsWithNameAndType(... "__CFStringMakeConstantString")

You can also use: 

SEL sel_registerName(const char *str);

This will register the name regardless of what it is or if it is valid.

One other way to do this is to get the selector by running and expression first and we could cache this in the objective C runtime:

(lldb) expr --raw -- @selector(foo)
(SEL) $3 = 0x00000001001000e0
(lldb) memory read 0x00000001001000e0
0x1001000e0: 66 6f 6f 00 ff 7f 00 00 2c 45 28 8c ff 7f 00 00  foo.....,E(.....
0x1001000f0: 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

This will give you a selector you can then use in subsequent expressions which already lives down in the process being debugged. Then you don't need to worry about copying it down when you call a function.


> 
> to get the pointer to the function (that goes fine)
> 
> ValueList args;
> Value strname((uint8_t*)value.c_str(), value.length() + 1);
> strname.SetContext(Value::eContextTypeClangType, ast_context->GetCStringType(true));
> args.PushValue(strname);
> 
> auto rettype = ast_context->CreatePointerType (ast_context->GetBuiltInType_void());
> 
> Value ret;
> ret.SetContext(Value::eContextTypeClangType, rettype);
> 
> ClangFunction func (*GetBestExecutionContextScope(),
>                    ast,
>                    rettype,
>                    *fn,
>                    args);
> 
>    func.InsertFunction(m_process, wrapper_struct_addr, error_stream);
> 
> 
> 
>    ExecutionResults results = func.ExecuteFunction (m_process,
>      &wrapper_struct_addr,
>      error_stream,
>      true,
>      0 /* no timeout */,
>      true,
>      true,
>      true,
>      ret);
> 
> 
> 
> 
> However this fails with a stop_reason exception, so I think I'm doing something wrong. Is this the right way to pass a char* to the process on the other side? If so, what could I be missing, if not, what is?

All "ast_context->GetCStringType(true)" gets you is a "const char *" type. When copying the argument down, it will just copy the pointer, not the string. Your function above will copy down the string address in the _host_ which is not what you want. I don't think our function running takes care of copying down string values.

If you use the "@selector(NAME)" expression trick you can avoid this. 

You also need to be aware that someone might have the objective C runtime lock. Also, if you crash while running an objc selector on an object, you might keep the objc runtime lock locked and hose your entire program if your expression fails to run. The minimize this, you will want to make sure that when you run your expression you allow other threads to run. You will need to check what happens when you supply a zero timeout (no timeout) and say other threads can run, and make sure other threads get a chance to run.

Greg







More information about the lldb-dev mailing list