Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[lldb] Add a test for user-defined objc_copyRealizedClassList_nolock
LLDB evaluates some utility expression to update the Objective-C class list that ends up calling function such as `free` or `objc_copyRealizedClassList_nolock`. This adds a test that just tries to define our own bogus version of `objc_copyRealizedClassList_nolock`. It just tests that LLDB doesn't crash as we currently don't have a way to tell LLDB to look for the function in a specific library. Reviewed By: JDevlieghere Differential Revision: https://reviews.llvm.org/D107778
- Loading branch information
Showing
3 changed files
with
61 additions
and
0 deletions.
There are no files selected for viewing
4 changes: 4 additions & 0 deletions
4
lldb/test/API/lang/objc/conflicting-class-list-function-from-user/Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
OBJC_SOURCES := main.m | ||
LD_EXTRAS := -lobjc -framework Foundation | ||
|
||
include Makefile.rules |
30 changes: 30 additions & 0 deletions
30
.../lang/objc/conflicting-class-list-function-from-user/TestObjCClassListFunctionFromUser.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import lldb | ||
from lldbsuite.test.decorators import * | ||
from lldbsuite.test.lldbtest import * | ||
from lldbsuite.test import lldbutil | ||
|
||
class TestCase(TestBase): | ||
|
||
mydir = TestBase.compute_mydir(__file__) | ||
|
||
@skipUnlessDarwin | ||
# LLDB ends up calling the user-defined function (but at least doesn't | ||
# crash). | ||
@expectedFailureDarwin | ||
def test(self): | ||
""" | ||
Tests LLDB's behaviour if the user defines their own conflicting | ||
objc_copyRealizedClassList_nolock function. | ||
""" | ||
|
||
self.build() | ||
lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.m")) | ||
|
||
# Get the (dynamic) type of our 'id' variable so that our Objective-C | ||
# runtime information is updated. | ||
str_val = self.expect_expr("custom_class") | ||
dyn_val = str_val.GetDynamicValue(lldb.eDynamicCanRunTarget) | ||
|
||
# We should have retrieved the proper class list even in presence of | ||
# the user-defined function. | ||
self.assertEqual(dyn_val.GetTypeName(), "CustomClass *") |
27 changes: 27 additions & 0 deletions
27
lldb/test/API/lang/objc/conflicting-class-list-function-from-user/main.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#import <Foundation/Foundation.h> | ||
#include <stdlib.h> | ||
|
||
// A function with this signature will be called by LLDB to retrieve the | ||
// Objective-C class list. We shouldn't call this function that is defined | ||
// by the user if possible. | ||
Class *objc_copyRealizedClassList_nolock(unsigned int *outCount) { | ||
// Don't try to implement this properly but just abort. | ||
abort(); | ||
} | ||
|
||
// Define some custom class that makes LLDB read the Objective-C class list. | ||
@interface CustomClass : NSObject { | ||
}; | ||
@end | ||
@implementation CustomClass | ||
@end | ||
|
||
int main(int argc, char **argv) { | ||
id custom_class = [[CustomClass alloc] init]; | ||
// Make sure our trap function is emitted but never called (the test doesn't | ||
// launch the executable with any args). | ||
if (argc == 123) { | ||
objc_copyRealizedClassList_nolock(0); | ||
} | ||
return 0; // break here | ||
} |