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;
|
StreamString install_errors;
|
||||||
|
|
||||||
if (!dynamic_checkers->Install(install_errors, exe_ctx))
|
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;
|
return result_valobj_sp;
|
||||||
|
}
|
||||||
|
|
||||||
exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
|
exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -231,7 +231,7 @@ AppleObjCRuntime::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others
|
||||||
// Static Functions
|
// Static Functions
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
enum AppleObjCRuntime::RuntimeVersions
|
enum AppleObjCRuntime::RuntimeVersions
|
||||||
AppleObjCRuntime::GetObjCVersion (Process *process)
|
AppleObjCRuntime::GetObjCVersion (Process *process, ModuleSP &objc_module_sp)
|
||||||
{
|
{
|
||||||
ModuleList &images = process->GetTarget().GetImages();
|
ModuleList &images = process->GetTarget().GetImages();
|
||||||
size_t num_images = images.GetSize();
|
size_t num_images = images.GetSize();
|
||||||
|
@ -240,6 +240,7 @@ AppleObjCRuntime::GetObjCVersion (Process *process)
|
||||||
ModuleSP module_sp = images.GetModuleAtIndex(i);
|
ModuleSP module_sp = images.GetModuleAtIndex(i);
|
||||||
if (AppleIsModuleObjCLibrary (module_sp))
|
if (AppleIsModuleObjCLibrary (module_sp))
|
||||||
{
|
{
|
||||||
|
objc_module_sp = module_sp;
|
||||||
ObjectFile *ofile = module_sp->GetObjectFile();
|
ObjectFile *ofile = module_sp->GetObjectFile();
|
||||||
if (!ofile)
|
if (!ofile)
|
||||||
return eObjC_VersionUnknown;
|
return eObjC_VersionUnknown;
|
||||||
|
|
|
@ -74,7 +74,7 @@ protected:
|
||||||
AppleIsModuleObjCLibrary (const lldb::ModuleSP &module_sp);
|
AppleIsModuleObjCLibrary (const lldb::ModuleSP &module_sp);
|
||||||
|
|
||||||
static enum AppleObjCRuntime::RuntimeVersions
|
static enum AppleObjCRuntime::RuntimeVersions
|
||||||
GetObjCVersion (Process *process);
|
GetObjCVersion (Process *process, ModuleSP &objc_module_sp);
|
||||||
|
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
// PluginInterface protocol
|
// PluginInterface protocol
|
||||||
|
|
|
@ -172,7 +172,9 @@ AppleObjCRuntimeV1::CreateInstance (Process *process, lldb::LanguageType languag
|
||||||
// sure we aren't using the V1 runtime.
|
// sure we aren't using the V1 runtime.
|
||||||
if (language == eLanguageTypeObjC)
|
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);
|
return new AppleObjCRuntimeV1 (process);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -231,22 +233,36 @@ AppleObjCRuntimeV1::SetExceptionBreakpoints ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BufStruct {
|
||||||
|
char contents[2048];
|
||||||
|
};
|
||||||
|
|
||||||
ClangUtilityFunction *
|
ClangUtilityFunction *
|
||||||
AppleObjCRuntimeV1::CreateObjectChecker(const char *name)
|
AppleObjCRuntimeV1::CreateObjectChecker(const char *name)
|
||||||
{
|
{
|
||||||
// char buf[256];
|
std::auto_ptr<BufStruct> buf(new BufStruct);
|
||||||
//
|
|
||||||
// assert(snprintf(&buf[0], sizeof(buf),
|
assert(snprintf(&buf->contents[0], sizeof(buf->contents),
|
||||||
// "extern \"C\" int gdb_object_getClass(void *);"
|
"struct __objc_class \n"
|
||||||
// "extern \"C\" void "
|
"{ \n"
|
||||||
// "%s(void *$__lldb_arg_obj)"
|
" struct __objc_class *isa; \n"
|
||||||
// "{"
|
" struct __objc_class *super_class; \n"
|
||||||
// " void **isa_ptr = (void **)$__lldb_arg_obj;"
|
" const char *name; \n"
|
||||||
// " if (!isa_ptr || !gdb_class_getClass(*isa_ptr))"
|
" // rest of struct elided because unused \n"
|
||||||
// " abort();"
|
"}; \n"
|
||||||
// "}",
|
" \n"
|
||||||
// name) < sizeof(buf));
|
"struct __objc_object \n"
|
||||||
//
|
"{ \n"
|
||||||
// return new ClangUtilityFunction(buf, name);
|
" struct __objc_class *isa; \n"
|
||||||
return NULL;
|
"}; \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 *pluginDesc = "Apple Objective C Language Runtime - Version 2";
|
||||||
static const char *pluginShort = "language.apple.objc.v2";
|
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
|
bool
|
||||||
AppleObjCRuntimeV2::GetObjectDescription (Stream &str, ValueObject &object, ExecutionContextScope *exe_scope)
|
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.
|
// sure we aren't using the V1 runtime.
|
||||||
if (language == eLanguageTypeObjC)
|
if (language == eLanguageTypeObjC)
|
||||||
{
|
{
|
||||||
if (AppleObjCRuntime::GetObjCVersion (process) == AppleObjCRuntime::eObjC_V2)
|
ModuleSP objc_module_sp;
|
||||||
return new AppleObjCRuntimeV2 (process);
|
|
||||||
|
if (AppleObjCRuntime::GetObjCVersion (process, objc_module_sp) == AppleObjCRuntime::eObjC_V2)
|
||||||
|
return new AppleObjCRuntimeV2 (process, objc_module_sp);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -231,21 +239,40 @@ AppleObjCRuntimeV2::SetExceptionBreakpoints ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BufStruct {
|
||||||
|
char contents[1024];
|
||||||
|
};
|
||||||
|
|
||||||
ClangUtilityFunction *
|
ClangUtilityFunction *
|
||||||
AppleObjCRuntimeV2::CreateObjectChecker(const char *name)
|
AppleObjCRuntimeV2::CreateObjectChecker(const char *name)
|
||||||
{
|
{
|
||||||
char buf[256];
|
std::auto_ptr<BufStruct> buf(new BufStruct);
|
||||||
|
|
||||||
assert(snprintf(&buf[0], sizeof(buf),
|
if (m_has_object_getClass)
|
||||||
"extern \"C\" int gdb_object_getClass(void *);"
|
{
|
||||||
"extern \"C\" void "
|
assert(snprintf(&buf->contents[0], sizeof(buf->contents),
|
||||||
"%s(void *$__lldb_arg_obj)"
|
"extern \"C\" int gdb_object_getClass(void *); \n"
|
||||||
"{"
|
"extern \"C\" void \n"
|
||||||
" void **isa_ptr = (void **)$__lldb_arg_obj;"
|
"%s(void *$__lldb_arg_obj) \n"
|
||||||
" if (!isa_ptr || !gdb_class_getClass(*isa_ptr))"
|
"{ \n"
|
||||||
" abort();"
|
" if (!gdb_object_getClass($__lldb_arg_obj)) \n"
|
||||||
"}",
|
" abort(); \n"
|
||||||
name) < sizeof(buf));
|
"} \n",
|
||||||
|
name) < sizeof(buf->contents));
|
||||||
return new ClangUtilityFunction(buf, name);
|
}
|
||||||
|
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:
|
protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AppleObjCRuntimeV2(Process *process) :
|
AppleObjCRuntimeV2(Process *process, ModuleSP &objc_module_sp);
|
||||||
lldb_private::AppleObjCRuntime (process)
|
|
||||||
{ } // Call CreateInstance instead.
|
bool m_has_object_getClass;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lldb_private
|
} // namespace lldb_private
|
||||||
|
|
Loading…
Reference in New Issue