-
Notifications
You must be signed in to change notification settings - Fork 592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
can not find __block variables have been capture by the block #24
Comments
Hey! I'm happy to investigate a bit more. Do you have a particular code snippet for that? |
only _GetBlockStrongLayout() and FBGetBlockStrongReferences() functions in FBBlockStrongLayout.m were modified,
static void _GetBlockStrongLayout(void *block, NSMutableArray *objStrongArr) {
struct BlockLiteral *blockLiteral = block;
NSMutableIndexSet *objCopyLayout = [NSMutableIndexSet indexSet];
NSMutableIndexSet *objRefLayout = [NSMutableIndexSet indexSet];
/**
BLOCK_HAS_CTOR - Block has a C++ constructor/destructor, which gives us a good chance it retains
objects that are not pointer aligned, so omit them.
!BLOCK_HAS_COPY_DISPOSE - Block doesn't have a dispose function, so it does not retain objects and
we are not able to blackbox it.
*/
if ((blockLiteral->flags & BLOCK_HAS_CTOR)
|| !(blockLiteral->flags & BLOCK_HAS_COPY_DISPOSE)) {
return;
}
void (*dispose_helper)(void *src) = blockLiteral->descriptor->dispose_helper;
const size_t ptrSize = sizeof(void *);
// Figure out the number of pointers it takes to fill out the object, rounding up.
const size_t elements = (blockLiteral->descriptor->size + ptrSize - 1) / ptrSize;
const size_t count = (sizeof(struct BlockLiteral) + ptrSize -1)/ptrSize;
// Create a fake object of the appropriate length.
void *obj[elements];
void *detectors[elements];
for (size_t i = count; i < elements; ++i) {
FBBlockStrongRelationDetector *detector = [FBBlockStrongRelationDetector new];
obj[i] = detectors[i] = detector;
}
@autoreleasepool {
dispose_helper(obj);
}
// Run through the release detectors and add each one that got released to the object's
void **blockReference = block;
for (size_t i = count; i < elements; ++i) {
FBBlockStrongRelationDetector *detector = (FBBlockStrongRelationDetector *)(detectors[i]);
if (detector.isStrong) {
[objCopyLayout addIndex:i];
} else {
struct BlockByref *detectorRef = (struct BlockByref *)(blockReference[i]);
if (!malloc_zone_from_ptr(detectorRef) || !malloc_zone_from_ptr(detectorRef->forwarding)) {
continue;
}
if (detectorRef && detectorRef->forwarding && detectorRef->forwarding->size == 48 && detectorRef->refObj) {
struct BlockByref *detectorRefTmp = (struct BlockByref *)malloc(sizeof(struct BlockByref));
detectorRefTmp->forwarding = detectorRefTmp;
detectorRefTmp->flags = detectorRef->flags;
detectorRefTmp->size = 48;
detectorRefTmp->Block_byref_id_object_dispose = detectorRef->Block_byref_id_object_dispose;
detectorRefTmp->refObj = detector;
obj[i] = detectorRefTmp;
[objRefLayout addIndex:i];
}
}
}
[objCopyLayout enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
void **reference = &blockReference[idx];
if (reference && (*reference)) {
id object = (id)(*reference);
if (object) {
[objStrongArr addObject:object];
}
}
}];
@autoreleasepool {
dispose_helper(obj);
}
for (size_t i = count; i < elements; ++i) {
FBBlockStrongRelationDetector *detector = (FBBlockStrongRelationDetector *)(detectors[i]);
if ([objRefLayout containsIndex:i]) {
if (detector.isStrong) {
struct BlockByref *detectorRefTmp = (struct BlockByref *)(blockReference[i]);
[objStrongArr addObject:(id)detectorRefTmp->refObj];
}
// if here free detectorRef,application will abort, I guess dispose_helper() have free the memorry of struct __Block_byref_blockTest_1 *detectorRef , but when I open malloc scribble config, only detectorRefTmp->__Block_byref_id_object_copy detectorRefTmp->__Block_byref_id_object_dispose and detectorRefTmp->reobj is setted to 0x55
// struct BlockByref *detectorRef = (struct BlockByref *)(obj[i]);
// free(detectorRef);
}
// Destroy detectors
[detector trueRelease];
}
}
NSArray *FBGetBlockStrongReferences(void *block) {
if (!FBObjectIsBlock(block)) {
return nil;
}
NSMutableArray *results = [NSMutableArray new];
_GetBlockStrongLayout(block, results);
return [results autorelease];
}
and I add a struct define in FBBlockInterface.h
struct BlockByref {
void *isa;
struct BlockByref *forwarding;
int flags;
int size;
void (*Block_byref_id_object_copy)(void*, void*);
void (*Block_byref_id_object_dispose)(void*);
void *refObj;
};
… 在 2016年12月7日,上午3:42,Grzegorz Pstrucha ***@***.***> 写道:
Hey! I'm happy to investigate a bit more. Do you have a particular code snippet for that?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub <#24 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AWbKten0eOjPUwER-pTHrRM_jVukXXDtks5rFbqqgaJpZM4K-2NR>.
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
can not find __block variables have been capture by the block
The text was updated successfully, but these errors were encountered: