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:
Sean Callanan 2010-11-05 00:57:06 +00:00
parent 5822173bc8
commit 2a39652303
6 changed files with 89 additions and 37 deletions

View File

@ -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);
} }

View File

@ -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;

View File

@ -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

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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