forked from OSchip/llvm-project
Fixed error handling when the utility functions
that check pointer validity fail to parse. Now lldb does not crash in that case. Also added support for checking Objective-C class validity in the Version 1 runtime as well as Version 2 runtimes with varying levels of available debug support. llvm-svn: 118271
This commit is contained in:
parent
5822173bc8
commit
2a39652303
|
@ -449,8 +449,16 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
|
|||
StreamString install_errors;
|
||||
|
||||
if (!dynamic_checkers->Install(install_errors, exe_ctx))
|
||||
{
|
||||
if (install_errors.GetString().empty())
|
||||
error.SetErrorString ("couldn't install checkers, unknown error");
|
||||
else
|
||||
error.SetErrorString (install_errors.GetString().c_str());
|
||||
|
||||
result_valobj_sp.reset (new ValueObjectConstResult (error));
|
||||
return result_valobj_sp;
|
||||
|
||||
}
|
||||
|
||||
exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
|
||||
}
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@ AppleObjCRuntime::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others
|
|||
// Static Functions
|
||||
//------------------------------------------------------------------
|
||||
enum AppleObjCRuntime::RuntimeVersions
|
||||
AppleObjCRuntime::GetObjCVersion (Process *process)
|
||||
AppleObjCRuntime::GetObjCVersion (Process *process, ModuleSP &objc_module_sp)
|
||||
{
|
||||
ModuleList &images = process->GetTarget().GetImages();
|
||||
size_t num_images = images.GetSize();
|
||||
|
@ -240,6 +240,7 @@ AppleObjCRuntime::GetObjCVersion (Process *process)
|
|||
ModuleSP module_sp = images.GetModuleAtIndex(i);
|
||||
if (AppleIsModuleObjCLibrary (module_sp))
|
||||
{
|
||||
objc_module_sp = module_sp;
|
||||
ObjectFile *ofile = module_sp->GetObjectFile();
|
||||
if (!ofile)
|
||||
return eObjC_VersionUnknown;
|
||||
|
|
|
@ -74,7 +74,7 @@ protected:
|
|||
AppleIsModuleObjCLibrary (const lldb::ModuleSP &module_sp);
|
||||
|
||||
static enum AppleObjCRuntime::RuntimeVersions
|
||||
GetObjCVersion (Process *process);
|
||||
GetObjCVersion (Process *process, ModuleSP &objc_module_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// PluginInterface protocol
|
||||
|
|
|
@ -172,7 +172,9 @@ AppleObjCRuntimeV1::CreateInstance (Process *process, lldb::LanguageType languag
|
|||
// sure we aren't using the V1 runtime.
|
||||
if (language == eLanguageTypeObjC)
|
||||
{
|
||||
if (AppleObjCRuntime::GetObjCVersion (process) == AppleObjCRuntime::eObjC_V1)
|
||||
ModuleSP objc_module_sp;
|
||||
|
||||
if (AppleObjCRuntime::GetObjCVersion (process, objc_module_sp) == AppleObjCRuntime::eObjC_V1)
|
||||
return new AppleObjCRuntimeV1 (process);
|
||||
else
|
||||
return NULL;
|
||||
|
@ -231,22 +233,36 @@ AppleObjCRuntimeV1::SetExceptionBreakpoints ()
|
|||
}
|
||||
}
|
||||
|
||||
struct BufStruct {
|
||||
char contents[2048];
|
||||
};
|
||||
|
||||
ClangUtilityFunction *
|
||||
AppleObjCRuntimeV1::CreateObjectChecker(const char *name)
|
||||
{
|
||||
// char buf[256];
|
||||
//
|
||||
// assert(snprintf(&buf[0], sizeof(buf),
|
||||
// "extern \"C\" int gdb_object_getClass(void *);"
|
||||
// "extern \"C\" void "
|
||||
// "%s(void *$__lldb_arg_obj)"
|
||||
// "{"
|
||||
// " void **isa_ptr = (void **)$__lldb_arg_obj;"
|
||||
// " if (!isa_ptr || !gdb_class_getClass(*isa_ptr))"
|
||||
// " abort();"
|
||||
// "}",
|
||||
// name) < sizeof(buf));
|
||||
//
|
||||
// return new ClangUtilityFunction(buf, name);
|
||||
return NULL;
|
||||
std::auto_ptr<BufStruct> buf(new BufStruct);
|
||||
|
||||
assert(snprintf(&buf->contents[0], sizeof(buf->contents),
|
||||
"struct __objc_class \n"
|
||||
"{ \n"
|
||||
" struct __objc_class *isa; \n"
|
||||
" struct __objc_class *super_class; \n"
|
||||
" const char *name; \n"
|
||||
" // rest of struct elided because unused \n"
|
||||
"}; \n"
|
||||
" \n"
|
||||
"struct __objc_object \n"
|
||||
"{ \n"
|
||||
" struct __objc_class *isa; \n"
|
||||
"}; \n"
|
||||
" \n"
|
||||
"extern \"C\" void \n"
|
||||
"%s(void *$__lldb_arg_obj) \n"
|
||||
"{ \n"
|
||||
" struct __objc_object *obj = (struct __objc_object*)$__lldb_arg_obj; \n"
|
||||
" strlen(obj->isa->name); \n"
|
||||
"} \n",
|
||||
name) < sizeof(buf->contents));
|
||||
|
||||
return new ClangUtilityFunction(buf->contents, name);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,12 @@ static const char *pluginName = "AppleObjCRuntimeV2";
|
|||
static const char *pluginDesc = "Apple Objective C Language Runtime - Version 2";
|
||||
static const char *pluginShort = "language.apple.objc.v2";
|
||||
|
||||
AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process, ModuleSP &objc_module_sp) :
|
||||
lldb_private::AppleObjCRuntime (process)
|
||||
{
|
||||
m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(ConstString("gdb_object_getClass")) != NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
AppleObjCRuntimeV2::GetObjectDescription (Stream &str, ValueObject &object, ExecutionContextScope *exe_scope)
|
||||
{
|
||||
|
@ -172,8 +178,10 @@ AppleObjCRuntimeV2::CreateInstance (Process *process, lldb::LanguageType languag
|
|||
// sure we aren't using the V1 runtime.
|
||||
if (language == eLanguageTypeObjC)
|
||||
{
|
||||
if (AppleObjCRuntime::GetObjCVersion (process) == AppleObjCRuntime::eObjC_V2)
|
||||
return new AppleObjCRuntimeV2 (process);
|
||||
ModuleSP objc_module_sp;
|
||||
|
||||
if (AppleObjCRuntime::GetObjCVersion (process, objc_module_sp) == AppleObjCRuntime::eObjC_V2)
|
||||
return new AppleObjCRuntimeV2 (process, objc_module_sp);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
@ -231,21 +239,40 @@ AppleObjCRuntimeV2::SetExceptionBreakpoints ()
|
|||
}
|
||||
}
|
||||
|
||||
struct BufStruct {
|
||||
char contents[1024];
|
||||
};
|
||||
|
||||
ClangUtilityFunction *
|
||||
AppleObjCRuntimeV2::CreateObjectChecker(const char *name)
|
||||
{
|
||||
char buf[256];
|
||||
std::auto_ptr<BufStruct> buf(new BufStruct);
|
||||
|
||||
assert(snprintf(&buf[0], sizeof(buf),
|
||||
"extern \"C\" int gdb_object_getClass(void *);"
|
||||
"extern \"C\" void "
|
||||
"%s(void *$__lldb_arg_obj)"
|
||||
"{"
|
||||
" void **isa_ptr = (void **)$__lldb_arg_obj;"
|
||||
" if (!isa_ptr || !gdb_class_getClass(*isa_ptr))"
|
||||
" abort();"
|
||||
"}",
|
||||
name) < sizeof(buf));
|
||||
|
||||
return new ClangUtilityFunction(buf, name);
|
||||
if (m_has_object_getClass)
|
||||
{
|
||||
assert(snprintf(&buf->contents[0], sizeof(buf->contents),
|
||||
"extern \"C\" int gdb_object_getClass(void *); \n"
|
||||
"extern \"C\" void \n"
|
||||
"%s(void *$__lldb_arg_obj) \n"
|
||||
"{ \n"
|
||||
" if (!gdb_object_getClass($__lldb_arg_obj)) \n"
|
||||
" abort(); \n"
|
||||
"} \n",
|
||||
name) < sizeof(buf->contents));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(snprintf(&buf->contents[0], sizeof(buf->contents),
|
||||
"extern \"C\" int gdb_class_getClass(void *); \n"
|
||||
"extern \"C\" void \n"
|
||||
"%s(void *$__lldb_arg_obj) \n"
|
||||
"{ \n"
|
||||
" void **isa_ptr = (void **)$__lldb_arg_obj; \n"
|
||||
" if (!isa_ptr || !gdb_class_getClass(*isa_ptr)) \n"
|
||||
" abort(); \n"
|
||||
"} \n",
|
||||
name) < sizeof(buf->contents));
|
||||
}
|
||||
|
||||
return new ClangUtilityFunction(buf->contents, name);
|
||||
}
|
||||
|
|
|
@ -74,9 +74,9 @@ public:
|
|||
protected:
|
||||
|
||||
private:
|
||||
AppleObjCRuntimeV2(Process *process) :
|
||||
lldb_private::AppleObjCRuntime (process)
|
||||
{ } // Call CreateInstance instead.
|
||||
AppleObjCRuntimeV2(Process *process, ModuleSP &objc_module_sp);
|
||||
|
||||
bool m_has_object_getClass;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
Loading…
Reference in New Issue