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

View File

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

View File

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

View File

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

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

View File

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