From 50b5ee50238fbd8ea5633204a21723825786c00c Mon Sep 17 00:00:00 2001 From: Enrico Granata Date: Sat, 16 Mar 2013 00:50:25 +0000 Subject: [PATCH] Converting more data formatters to C++ - NSBundle, CFBinaryHeap, NSMachPort and NSNotification llvm-svn: 177213 --- lldb/examples/summaries/cocoa/CFBag.py | 3 +- lldb/examples/summaries/cocoa/CFBinaryHeap.py | 3 +- lldb/examples/summaries/cocoa/NSBundle.py | 3 +- lldb/examples/summaries/cocoa/NSMachPort.py | 3 +- lldb/examples/summaries/cocoa/NSNotification.py | 3 +- .../lldb/DataFormatters/CXXFormatterFunctions.h | 9 ++ .../DataFormatters/CXXFormatterFunctions.cpp | 161 ++++++++++++++++++++- lldb/source/DataFormatters/FormatManager.cpp | 12 +- 8 files changed, 185 insertions(+), 12 deletions(-) diff --git a/lldb/examples/summaries/cocoa/CFBag.py b/lldb/examples/summaries/cocoa/CFBag.py index 7c7493e..37d14a4 100644 --- a/lldb/examples/summaries/cocoa/CFBag.py +++ b/lldb/examples/summaries/cocoa/CFBag.py @@ -5,7 +5,8 @@ part of The LLVM Compiler Infrastructure This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details. """ -# summary provider for CFBag +# example summary provider for CFBag +# the real summary is now C++ code built into LLDB import lldb import ctypes import lldb.runtime.objc.objc_runtime diff --git a/lldb/examples/summaries/cocoa/CFBinaryHeap.py b/lldb/examples/summaries/cocoa/CFBinaryHeap.py index 1b7183d..2348a89 100644 --- a/lldb/examples/summaries/cocoa/CFBinaryHeap.py +++ b/lldb/examples/summaries/cocoa/CFBinaryHeap.py @@ -5,7 +5,8 @@ part of The LLVM Compiler Infrastructure This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details. """ -# summary provider for CFBinaryHeap +# example summary provider for CFBinaryHeap +# the real summary is now C++ code built into LLDB import lldb import ctypes import lldb.runtime.objc.objc_runtime diff --git a/lldb/examples/summaries/cocoa/NSBundle.py b/lldb/examples/summaries/cocoa/NSBundle.py index 342ccfa..1f6a7dd3 100644 --- a/lldb/examples/summaries/cocoa/NSBundle.py +++ b/lldb/examples/summaries/cocoa/NSBundle.py @@ -5,7 +5,8 @@ part of The LLVM Compiler Infrastructure This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details. """ -# summary provider for NSBundle +# example summary provider for NSBundle +# the real summary is now C++ code built into LLDB import lldb import ctypes import lldb.runtime.objc.objc_runtime diff --git a/lldb/examples/summaries/cocoa/NSMachPort.py b/lldb/examples/summaries/cocoa/NSMachPort.py index ecb4b75..554d2ca 100644 --- a/lldb/examples/summaries/cocoa/NSMachPort.py +++ b/lldb/examples/summaries/cocoa/NSMachPort.py @@ -5,7 +5,8 @@ part of The LLVM Compiler Infrastructure This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details. """ -# summary provider for NSData +# example summary provider for NSMachPort +# the real summary is now C++ code built into LLDB import lldb import ctypes import lldb.runtime.objc.objc_runtime diff --git a/lldb/examples/summaries/cocoa/NSNotification.py b/lldb/examples/summaries/cocoa/NSNotification.py index 8d49caa..33c2006 100644 --- a/lldb/examples/summaries/cocoa/NSNotification.py +++ b/lldb/examples/summaries/cocoa/NSNotification.py @@ -5,7 +5,8 @@ part of The LLVM Compiler Infrastructure This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details. """ -# summary provider for class NSNotification +# example summary provider for NSNotification +# the real summary is now C++ code built into LLDB import lldb.runtime.objc.objc_runtime import lldb.formatters.metrics import CFString diff --git a/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h b/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h index f06467e..8ba709e 100644 --- a/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h +++ b/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h @@ -95,9 +95,18 @@ namespace lldb_private { NSNumberSummaryProvider (ValueObject& valobj, Stream& stream); bool + NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream); + + bool + NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream); + + bool CFBagSummaryProvider (ValueObject& valobj, Stream& stream); bool + CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream); + + bool NSBundleSummaryProvider (ValueObject& valobj, Stream& stream); bool diff --git a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp index 1107566..89e156d 100644 --- a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp +++ b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp @@ -688,6 +688,102 @@ lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& } bool +lldb_private::formatters::NSNotificationSummaryProvider (ValueObject& valobj, Stream& stream) +{ + ProcessSP process_sp = valobj.GetProcessSP(); + if (!process_sp) + return false; + + ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); + + if (!runtime) + return false; + + ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); + + if (!descriptor.get() || !descriptor->IsValid()) + return false; + + uint32_t ptr_size = process_sp->GetAddressByteSize(); + + lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); + + if (!valobj_addr) + return false; + + const char* class_name = descriptor->GetClassName().GetCString(); + + if (!class_name || !*class_name) + return false; + + if (!strcmp(class_name,"NSConcreteNotification")) + { + uint64_t offset = ptr_size; + ClangASTType type(valobj.GetClangAST(),valobj.GetClangType()); + ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, type, true)); + StreamString summary_stream; + bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream); + if (was_nsstring_ok && summary_stream.GetSize() > 0) + { + stream.Printf("%s",summary_stream.GetData()); + return true; + } + } + // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle] + // which is encoded differently and needs to be handled by running code + return ExtractSummaryFromObjCExpression(valobj, "NSString*", "name", stream); +} + +bool +lldb_private::formatters::NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream) +{ + ProcessSP process_sp = valobj.GetProcessSP(); + if (!process_sp) + return false; + + ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); + + if (!runtime) + return false; + + ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); + + if (!descriptor.get() || !descriptor->IsValid()) + return false; + + uint32_t ptr_size = process_sp->GetAddressByteSize(); + + lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); + + if (!valobj_addr) + return false; + + const char* class_name = descriptor->GetClassName().GetCString(); + + if (!class_name || !*class_name) + return false; + + uint64_t port_number = 0; + + do + { + if (!strcmp(class_name,"NSMachPort")) + { + uint64_t offset = (ptr_size == 4 ? 12 : 20); + Error error; + port_number = process_sp->ReadUnsignedIntegerFromMemory(offset+valobj_addr, 4, 0, error); + if (error.Success()) + break; + } + if (!ExtractValueFromObjCExpression(valobj, "int", "machPort", port_number)) + return false; + } while (false); + + stream.Printf("mach port: %u",(uint32_t)(port_number & 0x00000000FFFFFFFF)); + return true; +} + +bool lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream) { ProcessSP process_sp = valobj.GetProcessSP(); @@ -726,7 +822,6 @@ lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& str if (is_type_ok == false) { -// num_children_vo = self.valobj.CreateValueFromExpression("count","(int)CFBagGetCount(" + stream.GetData() + " )") StackFrameSP frame_sp(valobj.GetFrameSP()); if (!frame_sp) return false; @@ -753,6 +848,70 @@ lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& str } bool +lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream) +{ + ProcessSP process_sp = valobj.GetProcessSP(); + if (!process_sp) + return false; + + ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); + + if (!runtime) + return false; + + ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); + + if (!descriptor.get() || !descriptor->IsValid()) + return false; + + uint32_t ptr_size = process_sp->GetAddressByteSize(); + + lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); + + if (!valobj_addr) + return false; + + uint32_t count = 0; + + bool is_type_ok = false; // check to see if this is a CFBinaryHeap we know about + if (descriptor->IsCFType()) + { + ConstString type_name(valobj.GetTypeName()); + if (type_name == ConstString("__CFBinaryHeap") || type_name == ConstString("const struct __CFBinaryHeap")) + { + if (valobj.IsPointerType()) + is_type_ok = true; + } + } + + if (is_type_ok == false) + { + StackFrameSP frame_sp(valobj.GetFrameSP()); + if (!frame_sp) + return false; + ValueObjectSP count_sp; + StreamString expr; + expr.Printf("(int)CFBinaryHeapGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue()); + if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExecutionCompleted) + return false; + if (!count_sp) + return false; + count = count_sp->GetValueAsUnsigned(0); + } + else + { + uint32_t offset = 2*ptr_size; + Error error; + count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error); + if (error.Fail()) + return false; + } + stream.Printf("@\"%u item%s\"", + count,(count == 1 ? "" : "s")); + return true; +} + +bool lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream) { ProcessSP process_sp = valobj.GetProcessSP(); diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index b13c468..afc88d4 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -926,8 +926,8 @@ FormatManager::LoadObjCFormatters() AddCXXSummary(appkit_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("const struct __CFBag"), appkit_flags); AddCXXSummary(appkit_category_sp,lldb_private::formatters::CFBagSummaryProvider, "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags); - AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("CFBinaryHeapRef"), appkit_flags); - AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("__CFBinaryHeap"), appkit_flags); + AddCXXSummary(appkit_category_sp,lldb_private::formatters::CFBinaryHeapSummaryProvider, "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"), appkit_flags); + AddCXXSummary(appkit_category_sp,lldb_private::formatters::CFBinaryHeapSummaryProvider, "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"), appkit_flags); AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSString"), appkit_flags); AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFStringRef"), appkit_flags); @@ -952,10 +952,10 @@ FormatManager::LoadObjCFormatters() AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider, "NSData summary provider", ConstString("CFDataRef"), appkit_flags); AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider, "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags); - AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSMachPort.NSMachPort_SummaryProvider", ConstString("NSMachPort"), appkit_flags); - - AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSNotification.NSNotification_SummaryProvider", ConstString("NSNotification"), appkit_flags); - AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSNotification.NSNotification_SummaryProvider", ConstString("NSConcreteNotification"), appkit_flags); + AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSMachPortSummaryProvider, "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags); + + AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSNotification"), appkit_flags); + AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, "NSNotification summary provider", ConstString("NSConcreteNotification"), appkit_flags); AddStringSummary(appkit_category_sp, "domain: ${var._domain} - code: ${var._code}", ConstString("NSError"), appkit_flags); AddStringSummary(appkit_category_sp,"name:${var.name%S} reason:${var.reason%S}",ConstString("NSException"),appkit_flags); -- 2.7.4