I am creating a library for HTTPS access using NSURLSession.
My library is built with non-ARC.
I'm trying to create a class like this:
@interface MyURLSession : NSObject <NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
:
@property (nonatomic, assign) MyInputStream *inputStream;
:
@end
For the GET Method, I created a task with dataTaskWithRequest and was able to access it without memory leaks.
As for the POST Method, when I created and processed the task with uploadTaskWithStreamedRequest, many memory leaks was detected in Leaks of Instruments.
Specifically, calling completionHandler(_inputStream) in URLSession:task:needNewBodyStream: leaks.
I think that many other leaks are caused by passing the _inputStream to the completionHandler.
Searching Leaks for HTTP, Session, and Stream words looks like this:
Snapshot Growth Persistent
MyInputStream 176 Bytes 1
CFHTTPMessage 1.72 KiB 6
HTTP2Connection 1.06 KiB 2
HTTP2Stream 928 Bytes 2
HTTPConnectionCacheKey 384 Bytes 3
HTTP2ConnectionCache 288 Bytes 2
HTTP2ConnectionCacheEntry 256 Bytes 2
HTTPHeaderDict 192 Bytes 6
std::__1::__shared_ptr_pointer<HTTP2Stream*, std::__1::default_delete<HTTP2Stream>, std::__1::allocator<HTTP2Stream> > 64 Bytes 2
__NSCFURLSessionConfiguration 512 Bytes 1
__NSURLSessionLocal 368 Bytes 1
HTTP2Stream 928 Bytes 2
RequestBodyStreamProvider 352 Bytes 2
_CFStreamDelegate 128 Bytes 2
std::__1::__shared_ptr_pointer<HTTP2Stream*, std::__1::default_delete<HTTP2Stream>, std::__1::allocator<HTTP2Stream> > 64 Bytes 2
std::__1::__shared_ptr_pointer<__CFReadStream*, Deleter_CFRelease, std::__1::allocator<__CFReadStream> > 64 Bytes 2
std::__1::__shared_ptr_pointer<BlockHolderVar<CFStreamError>*, SmartBlockWithArgs<CFStreamError>::Deleter, std::__1::allocator<BlockHolderVar<CFStreamError> > > 64 Bytes 2
I also searched Leaks for words such as Task and Request, but couldn't find them.
Since the reference counter of _inputSteam is 1 in the end, it seems that the one passed by completionHandler is still referenced.
I tried releasing more reference counters once, and although _inputSteam was released, the other leaks weren't resolved.
Passing MyInputStream * inputSteam is a original derivative class of NSInputStream and is a simple class that just passes data using read:maxLength:.
Could you give me some advice on how to resolve those leaks?
Thanks.
My Environments:XCode 12.4, dev target:iOS 7.0+, Device:iPhone X(OS 12.1)
Post
Replies
Boosts
Views
Activity
environment: Apple clang version 14.0.3 (clang-1403.0.22.14.1)
I am trying to override c++ symbols at linking time for the purpose of inserting measurement code into an existing library.
Perhaps typical linkers would search for symbols in specifing order of library and adopt the first hit.
Xcode's ld apparently does this in units of a object file.
If you create one object file to override one function and link it first, but call another function in the same object file contained in the original library, that one will be adopted. As a result, you cannot override function.
To override a function, the function to be overridden must be moved to a new cpp file and separated from the object file.
Here is a sample program to test this.
https://onedrive.live.com/redir?resid=DD46698E2D493F32!395&authkey=!AJqfiva7CXIDI_Y&e=OaFlSr
As you can see in main.cpp, func() and bar() are called from main().
func() and bar() are implemented in func.cpp and bar.cpp, respectively.
They are linked to libTest.lib.
To override func(), link libTest2.lib implementing func2() in func2.cpp, before libTest.lib.
If you run make and look at the code with objdump -d a.out, you can see the override.
Because the content of func2() is return i+1, __Z4funci contains leal 1(%rdi), %eax.
Then, build with make clean and make CONCAT=1, func() and bar() are concatenated into one cpp file and compiled.
The generated a.out is checked in the same way, you will see movl %edi, %eax at same position which means return i; which is the content of func().
This sample is small in scale, but in a larger project, it can be quite a hassle to isolate the functions you want to override.
Is there any easier way to override the function?
Since the original function name cannot be changed, it is our policy not to use -alias symbol_name alternate_symbol_name.
Thanks.