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

Greg Clayton gclayton at apple.com
Tue Mar 5 10:10:27 PST 2013


Just to mention: the manual function calling is not really meant for public consumption at this point. The API was just made to work with for a few simple function calls.

Doing this right would involve something like compiling a snippet of source code, then mentioning what we want to access and change in that source code. For example if you had code like:

const char *jit_source = R("
#define MAX_SEL_NAME_LEN 1024
char g_selector_name[MAX_SEL_NAME_LEN];

id call_selector_on_object (id obj)
{
	SEL sel = sel_registerName(g_selector_name);
	return objc_msgSend (obj, sel);
}
");

Then you would compile this expression into a new class like ClangJITCode (which would need to be written), have accessors on it to get variable values:

ClangJITCode jit_code(triple);

Error err = jit_code.Compile (jit_source);
if (err.Success())
{
    jit_code.Install (process);

    if (jit_code.SetVariableValue ("g_selector_name", "count"))
    {
	ValueList args;
	Value id_value;
	id_value.XXX(); // Initialize ID value with the correct value
	args.Append(id_value);
	err = jit_code.CallFunction ("call_selector_on_object", id_value);
	...
    }
}

This would allow us to install more than one function at a time, keep them all in the process, and call each individual function as needed. This would be much more usable than the current model, but of course it will need to be written.

Greg


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")
> 
> 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?
> 
> Thanks,
> 
> Carlo Kok
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev




More information about the lldb-dev mailing list