Skip to content

Commit dff2733

Browse files
author
Your Name
committed
* NSInvocation does not raise anymore during -init as noone should raise during init
* NSAutoreleasePool name can now be 48-1 bytes long added animation.html generator for debugging some tests ("hidden" in test/TAO/forward)
1 parent 4db6a22 commit dff2733

20 files changed

+190
-54
lines changed

.mulle/share/env/environment-plugin.sh

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.mulle/share/env/version

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.mulle/share/sde/version/mulle-sde/cmake

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ only and for instance not on `<unistd.h>`.
1010

1111
| Release Version | Release Notes
1212
|-------------------------------------------------------|--------------
13-
| ![Mulle kybernetiK tag](https://img.shields.io/github/tag/mulle-objc/MulleObjC.svg?branch=release) [![Build Status](https://github.com/mulle-objc/MulleObjC/workflows/CI/badge.svg?branch=release)](//github.com/mulle-objc/MulleObjC/actions) | [RELEASENOTES](RELEASENOTES.md) |
13+
| ![Mulle kybernetiK tag](https://img.shields.io/github/tag/mulle-objc/MulleObjC.svg) [![Build Status](https://github.com/mulle-objc/MulleObjC/workflows/CI/badge.svg)](//github.com/mulle-objc/MulleObjC/actions) | [RELEASENOTES](RELEASENOTES.md) |
1414

1515

1616
## API

RELEASENOTES.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
## 0.25.0
22

3+
* NSInvocation does not raise anymore during -init as noone should raise during init
4+
* NSAutoreleasePool name can now be 48-1 bytes long
5+
36
* added new types `NSUIntegerAtomic` and `NSIntegerAtomic` to facilitate @property code
47
* experimental and *untested* `MulleProxy` class added
58
* added NSAutoreleasePool debugging facility to dump contents into CSV format for postprocessing with sqlite or scripts

cmake/share/InstallRpath.cmake

+9-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/MulleObjCIntegralType.h

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <mulle-c11/mulle-c11-bool.h>
1515
#include <mulle-c11/mulle-c11-integer.h>
16+
#include <mulle-thread/mulle-thread.h>
1617

1718
typedef enum
1819
{

src/class/NSAutoreleasePool.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
{
5757
NSAutoreleasePool *_owner;
5858
void *_storage;
59-
char _mulleNameUTF8String[ 32];
59+
char _mulleNameUTF8String[ 48];
6060
}
6161

6262
// MEMO: this is marked as threadsafe, but that's because its assumed
@@ -265,5 +265,11 @@ void MulleObjCDumpAutoreleasePoolsToFileIndexed( char *filename);
265265
MULLE_OBJC_GLOBAL
266266
void MulleObjCDumpAutoreleasePoolsToFILEWithOptions( FILE *fp, int indexed);
267267

268+
//
269+
// MEMO: like the functions above, you should only use them when you
270+
// are in the debugger and a breakpoint has happened, but for debugging
271+
// you can sometimes get by even in running programs, if threads are
272+
// waiting for each other.
273+
//
268274
MULLE_OBJC_GLOBAL
269275
unsigned long MulleObjCDumpAutoreleasePoolsFrame( void);

src/class/NSAutoreleasePool.m

+22-5
Original file line numberDiff line numberDiff line change
@@ -241,14 +241,18 @@ void mulle_objc_thread_done_poolconfiguration( struct _mulle_objc_universe *un
241241
- (char *) mulleNameUTF8String
242242
{
243243
if( ! _mulleNameUTF8String[ 0])
244-
mulle_snprintf( _mulleNameUTF8String, sizeof( _mulleNameUTF8String), "%p", self);
244+
mulle_snprintf( _mulleNameUTF8String, sizeof( _mulleNameUTF8String),
245+
"<NSAutoreleasePool %p>",
246+
MulleObjCInstanceGetClassNameUTF8String( self),
247+
self);
245248
return( &_mulleNameUTF8String[ 0]);
246249
}
247250

248251

249252
- (void) mulleSetNameUTF8String:(char *) s
250253
{
251254
strncpy( _mulleNameUTF8String, s ? s : "", sizeof( _mulleNameUTF8String) - 1);
255+
_mulleNameUTF8String[ sizeof( _mulleNameUTF8String) - 1] = 0;
252256
}
253257

254258

@@ -1181,7 +1185,10 @@ static inline void _dump_info_init( struct dump_info *p,
11811185
{
11821186
if( thread != info->thread.mainthread)
11831187
{
1184-
mulle__pointermap_set( &p->thread_index_map, thread, (void *) (intptr_t) thread_index, NULL);
1188+
mulle__pointermap_set( &p->thread_index_map,
1189+
thread,
1190+
(void *) (intptr_t) thread_index,
1191+
NULL);
11851192
++thread_index;
11861193
}
11871194
}
@@ -1190,6 +1197,9 @@ static inline void _dump_info_init( struct dump_info *p,
11901197

11911198
static inline void _dump_info_done( struct dump_info *p)
11921199
{
1200+
mulle_free( p->thread_name);
1201+
mulle_free( p->pool_name);
1202+
11931203
_mulle__pointermap_done( &p->thread_index_map, NULL);
11941204
_mulle__pointermap_done( &p->object_index_map, NULL);
11951205
}
@@ -1204,7 +1214,9 @@ static void _dumpinfo_dump_thread( struct dump_info *info,
12041214
struct _mulle_objc_poolconfiguration *config;
12051215

12061216
info->thread_adr = thread;
1207-
info->thread_name = [thread mulleNameUTF8String];
1217+
1218+
mulle_free( info->thread_name);
1219+
info->thread_name = mulle_strdup( [thread mulleNameUTF8String]);
12081220
info->thread_index = (int) index;
12091221
info->pool_index = 0;
12101222

@@ -1214,7 +1226,8 @@ static void _dumpinfo_dump_thread( struct dump_info *info,
12141226

12151227
for( pool = config->tail; pool; pool = pool->_owner)
12161228
{
1217-
info->pool_name = [pool mulleNameUTF8String];
1229+
mulle_free( info->pool_name);
1230+
info->pool_name = mulle_strdup( [pool mulleNameUTF8String]);
12181231
info->pool_adr = pool;
12191232

12201233
--info->pool_index;
@@ -1250,7 +1263,11 @@ static void _dumpinfo_dump_thread( struct dump_info *info,
12501263
_dump_info_done( &dump_info);
12511264
}
12521265

1253-
1266+
//
1267+
// Though we do a "lock" its just to block another
1268+
// MulleObjCDumpAutoreleasePoolsToFILEWithOptions, dumping other threads
1269+
// autoreleasepools is obviously risky.
1270+
//
12541271
void MulleObjCDumpAutoreleasePoolsToFILEWithOptions( FILE *fp, int options)
12551272
{
12561273
struct _mulle_objc_universe *universe;

src/class/NSInvocation.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
- (void) setSelector:(SEL) selector;
9090

9191
- (id) target;
92-
- (void) setTarget:target;
92+
- (void) setTarget:(id) target;
9393

9494
- (void) invoke;
9595
- (void) invokeWithTarget:(id) target;

src/class/NSInvocation.m

+8-16
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,9 @@ + (NSInvocation *) invocationWithMethodSignature:(NSMethodSignature *) signature
174174
void *extraBytes;
175175
struct _mulle_objc_infraclass *cls;
176176

177+
// MEMO: do not raise during construction of objects
177178
if( ! signature)
178-
{
179-
__mulle_objc_universe_raise_invalidargument( _mulle_objc_object_get_universe( self),
180-
"signature is nil");
181179
return( nil);
182-
}
183180

184181
// frame_size = [signature frameLength];
185182
// size = mulle_metaabi_sizeof_union( frame_size);
@@ -231,6 +228,9 @@ + (NSInvocation *) mulleInvocationWithTarget:(id) target
231228

232229
signature = [target methodSignatureForSelector:sel];
233230
invocation = [self invocationWithMethodSignature:signature];
231+
if( ! invocation)
232+
return( nil);
233+
234234
[invocation setTarget:target];
235235
[invocation setSelector:sel];
236236

@@ -268,13 +268,7 @@ + (NSInvocation *) mulleInvocationWithTarget:(id) target
268268
NSInvocation *invocation;
269269
NSMethodSignature *signature;
270270

271-
signature = [target methodSignatureForSelector:sel];
272-
if( ! signature)
273-
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method not found on target");
274-
if( [signature numberOfArguments] != 3)
275-
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method must accept one argument");
276-
if( [signature isVariadic])
277-
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method must not be variadic");
271+
signature = [target methodSignatureForSelector:sel];
278272

279273
invocation = [self invocationWithMethodSignature:signature];
280274
[invocation setTarget:target];
@@ -297,11 +291,7 @@ + (NSInvocation *) mulleInvocationWithTarget:(id) target
297291
void *adr;
298292
MulleObjCMethodSignatureTypeInfo *p;
299293
#endif
300-
signature = [target methodSignatureForSelector:sel];
301-
if( ! signature)
302-
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method %x not found on target", sel);
303-
if( [signature isVariadic])
304-
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method must not be variadic");
294+
signature = [target methodSignatureForSelector:sel];
305295

306296
invocation = [self invocationWithMethodSignature:signature];
307297
[invocation setTarget:target];
@@ -780,6 +770,8 @@ - (void) invokeWithTarget:(id) target
780770
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "NSInvocation: selector has not been set yet");
781771
if( ! _methodSignature)
782772
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "NSInvocation: methodSignature has not been set yet");
773+
if( [_methodSignature isVariadic])
774+
MulleObjCThrowInternalInconsistencyExceptionUTF8String( "method must not be variadic");
783775

784776
pType = [_methodSignature _methodMetaABIParameterType];
785777
rType = [_methodSignature _methodMetaABIReturnType];

src/class/NSObject.m

+5
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ - (void *) forward:(void *) _param MULLE_OBJC_THREADSAFE_METHOD
121121
}
122122
#endif
123123

124+
// MEMO: can't autorelease ahead of init, because init can return
125+
// nil and release object, or release object and return another
126+
// alloced one. So if -init raises, we leak and can't do much
127+
// about. -raise during -init == BAD
128+
//
124129
obj = [_cls alloc];
125130
obj = mulle_objc_object_call_variable_inline( obj,
126131
(mulle_objc_methodid_t) _cmd,

src/class/NSThread.m

+5-1
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,8 @@ - (id) mulleSetRunLoop:(id) runLoop
946946
id otherRunloop;
947947

948948
assert( ! runLoop || [runLoop mulleIsAccessibleByThread:self]);
949+
assert( ! _mulle_objc_object_is_finalized( (struct _mulle_objc_object *) self));
950+
949951
[runLoop retain];
950952
otherRunloop = __mulle_atomic_pointer_compare_and_swap( &self->_runLoop, runLoop, NULL);
951953
if( otherRunloop)
@@ -1107,7 +1109,9 @@ - (char *) mulleNameUTF8String
11071109

11081110
s = _mulle_atomic_pointer_read( &_nameUTF8String);
11091111
if( ! s)
1110-
s = MulleObjC_asprintf( "%p", self);
1112+
s = MulleObjC_asprintf( "<%s %p>",
1113+
MulleObjCInstanceGetClassNameUTF8String( self),
1114+
self);
11111115
return( s);
11121116
}
11131117

src/reflect/_MulleObjC-versioncheck.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#if defined( MULLE__OBJC__DEBUG_VERSION)
99
# ifndef MULLE__OBJC__DEBUG_VERSION_MIN
10-
# define MULLE__OBJC__DEBUG_VERSION_MIN ((0UL << 20) | (21 << 8) | 2)
10+
# define MULLE__OBJC__DEBUG_VERSION_MIN ((0UL << 20) | (21 << 8) | 3)
1111
# endif
1212
# ifndef MULLE__OBJC__DEBUG_VERSION_MAX
1313
# define MULLE__OBJC__DEBUG_VERSION_MAX ((0UL << 20) | (22 << 8) | 0)
@@ -22,10 +22,10 @@
2222

2323
#if defined( MULLE__OBJC__RUNTIME_VERSION)
2424
# ifndef MULLE__OBJC__RUNTIME_VERSION_MIN
25-
# define MULLE__OBJC__RUNTIME_VERSION_MIN ((0UL << 20) | (24 << 8) | 0)
25+
# define MULLE__OBJC__RUNTIME_VERSION_MIN ((0UL << 20) | (25 << 8) | 0)
2626
# endif
2727
# ifndef MULLE__OBJC__RUNTIME_VERSION_MAX
28-
# define MULLE__OBJC__RUNTIME_VERSION_MAX ((0UL << 20) | (25 << 8) | 0)
28+
# define MULLE__OBJC__RUNTIME_VERSION_MAX ((0UL << 20) | (26 << 8) | 0)
2929
# endif
3030
# if MULLE__OBJC__RUNTIME_VERSION < MULLE__OBJC__RUNTIME_VERSION_MIN
3131
# error "mulle-objc-runtime is too old"

test/.mulle/share/env/environment-plugin.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ export MULLE_SOURCETREE_SYMLINK='YES'
2222
#
2323
#
2424
#
25-
export MULLE_SDE_INSTALLED_VERSION="3.2.0"
25+
export MULLE_SDE_INSTALLED_VERSION="3.2.2"
2626

2727

test/.mulle/share/env/version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.3.0
1+
5.3.1

test/NSAutoreleasePool/pooldump.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ + (instancetype) objectWithNameUTF8String:(char *) s
4646
- (char *) mulleNameUTF8String
4747
{
4848
if( ! _mulleNameUTF8String[ 0])
49-
mulle_snprintf( _mulleNameUTF8String, sizeof( _mulleNameUTF8String), "%p", self);
49+
mulle_snprintf( _mulleNameUTF8String, sizeof( _mulleNameUTF8String), "<Foo %p>", self);
5050
return( &_mulleNameUTF8String[ 0]);
5151
}
5252

test/TAO/forward/TAOStrategyTest.inc

+19-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,24 @@ static void dump_trace_text( unsigned long nr, char *format, va_list args)
3333
}
3434

3535
mulle_vfprintf( fp, format, args);
36-
mulle_fprintf( fp, "\n");
37-
_mulle_stacktrace( NULL, 2, mulle_stacktrace_linefeed, fp);
36+
fclose( fp);
37+
}
38+
39+
40+
static void dump_trace_stack( unsigned long nr)
41+
{
42+
auto char buf[ 19 + 32 + 4 + 1];
43+
FILE *fp;
44+
45+
mulle_snprintf( buf, sizeof( buf), "NSAutoreleasePools_%06d.trc", nr);
46+
fp = fopen( buf, "w");
47+
if( ! fp)
48+
{
49+
perror( "fopen:");
50+
return;
51+
}
52+
53+
_mulle_stacktrace( NULL, 3, mulle_stacktrace_csv, fp);
3854

3955
fclose( fp);
4056
}
@@ -55,6 +71,7 @@ static void test_trace( char *format, ...)
5571
nr = MulleObjCDumpAutoreleasePoolsFrame();
5672
va_start( args, format);
5773
dump_trace_text( nr, format, args);
74+
dump_trace_stack( nr);
5875
va_end( args);
5976
}
6077
#endif

0 commit comments

Comments
 (0)