forked from OSchip/llvm-project
Fix a bug where we were trying to reconstruct ivars of ObjC types from the runtime in "expression parser mode"
The expression parser mode allows UnknownAnyTy to make it all the way through, but that is bad for ivars because it means type layout fails horribly (as in, clang crashes) This patch fixes the issue by using the "variables view mode", which masks UnknownAnyTy as empty-type, and pointer-to UnknownAnyTy as void* This, in turn, allows LLDB to properly reconstruct ivars of IMP type in ObjC type - as per accompanying test case Fixes rdar://21471326 llvm-svn: 240677
This commit is contained in:
parent
1f93e86768
commit
2d061e20f6
|
|
@ -496,7 +496,7 @@ AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl)
|
|||
if (!name || !type)
|
||||
return false;
|
||||
|
||||
const bool for_expression = true;
|
||||
const bool for_expression = false;
|
||||
|
||||
if (log)
|
||||
log->Printf("[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64, name, type, offset_ptr);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
myclass.o: myclass.h myclass.m
|
||||
$(CC) myclass.m -c -o myclass.o
|
||||
|
||||
repro: myclass.o repro.m
|
||||
$(CC) -g -O0 myclass.o repro.m -framework Foundation
|
||||
|
||||
cleanup:
|
||||
rm -r myclass.o
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
"""
|
||||
Test that dynamically discovered ivars of type IMP do not crash LLDB
|
||||
"""
|
||||
|
||||
import os, time
|
||||
import re
|
||||
import unittest2
|
||||
import lldb, lldbutil
|
||||
from lldbtest import *
|
||||
import commands
|
||||
|
||||
def execute_command (command):
|
||||
# print '%% %s' % (command)
|
||||
(exit_status, output) = commands.getstatusoutput (command)
|
||||
# if output:
|
||||
# print output
|
||||
# print 'status = %u' % (exit_status)
|
||||
return exit_status
|
||||
|
||||
class ObjCiVarIMPTestCase(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
@skipUnlessDarwin
|
||||
def test_imp_ivar_type(self):
|
||||
"""Test that dynamically discovered ivars of type IMP do not crash LLDB"""
|
||||
if self.getArchitecture() == 'i386':
|
||||
# rdar://problem/9946499
|
||||
self.skipTest("Dynamic types for ObjC V1 runtime not implemented")
|
||||
self.buildReproCase()
|
||||
self.runTheTest()
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
TestBase.setUp(self)
|
||||
|
||||
def buildReproCase (self):
|
||||
execute_command("make repro")
|
||||
|
||||
def runTheTest(self):
|
||||
"""MakeTest that dynamically discovered ivars of type IMP do not crash LLDB"""
|
||||
def cleanup():
|
||||
execute_command("make cleanup")
|
||||
self.addTearDownHook(cleanup)
|
||||
|
||||
exe = os.path.join(os.getcwd(), "a.out")
|
||||
|
||||
# Create a target from the debugger.
|
||||
|
||||
target = self.dbg.CreateTarget (exe)
|
||||
self.assertTrue(target, VALID_TARGET)
|
||||
|
||||
# Set up our breakpoint
|
||||
|
||||
bkpt = lldbutil.run_break_set_by_source_regexp (self, "break here")
|
||||
|
||||
# Now launch the process, and do not stop at the entry point.
|
||||
process = target.LaunchSimple (None, None, self.get_process_working_directory())
|
||||
|
||||
self.assertTrue(process.GetState() == lldb.eStateStopped,
|
||||
PROCESS_STOPPED)
|
||||
|
||||
self.expect('frame variable --ptr-depth=1 --show-types -d run -- object', substrs=[
|
||||
'(MyClass *) object = 0x',
|
||||
'(void *) myImp = 0x'
|
||||
])
|
||||
self.expect('disassemble --start-address `((MyClass*)object)->myImp`', substrs=[
|
||||
'-[MyClass init]'
|
||||
])
|
||||
|
||||
if __name__ == '__main__':
|
||||
import atexit
|
||||
lldb.SBDebugger.Initialize()
|
||||
atexit.register(lambda: lldb.SBDebugger.Terminate())
|
||||
unittest2.main()
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface MyClass : NSObject
|
||||
{}
|
||||
- (id)init;
|
||||
@end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "MyClass.h"
|
||||
|
||||
@implementation MyClass
|
||||
{
|
||||
IMP myImp;
|
||||
}
|
||||
- (id)init {
|
||||
if (self = [super init])
|
||||
{
|
||||
SEL theSelector = @selector(init);
|
||||
self->myImp = [self methodForSelector:theSelector];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "MyClass.h"
|
||||
|
||||
int main() {
|
||||
id object = [MyClass new];
|
||||
return 0; // break here
|
||||
}
|
||||
Loading…
Reference in New Issue