Leak when calling CFNetworkExecuteProxyAutoConfigurationURL on Mac
I am using CFNetwork APIs to detect OS proxy settings. My setup is heavily based on this:
https://github.com/adobe/chromium/blob/master/net/proxy/proxy_resolver_mac.cc
which is pretty much the same as this:
https://developer.apple.com/library/archive/samplecode/CFProxySupportTool/Introduction/Intro.html
I use CFNetworkCopyProxiesForURL to get the list of proxies, and for the PAC types, use CFNetworkExecuteProxyAutoConfigurationURL to fetch and execute the PAC script, immediately running the run loop on the current thread, which is already not on the ui thread.
This all works properly, and I have carefully combed through making sure that I am following the create rule to properly release results. However, when using Xcode instruments, I'm seeing that std::shared_ptrs to PAC::PACClient are leaked by _CFNetworkExecuteProxyAutoConfigurationURLDelegated. Since that object is never exposed to me, I'm not sure how I can control its release, but it is leaking. This is only an issue with fetching PAC files, explicit proxies do not leak. I have tried adding redundant CFRelease calls on all the CFDictionaries and such exposed to me to see if something was being over retained, but it didn't make a difference to the PACClient leak.
This is on Mac in a cpp file, not objective C, in a project with ARC on.
Has anyone encountered this leak and know how to prevent it?
Below is the snippet that executes the lookup, which is all the same steps from the above projects.
struct PACRequestInfo
CFURLRef url; // Caller gets this from a dictionary, doesn't need release
CFURLRef scriptURL; // Caller gets this from a dictionary, doesn't need release
CFMutableArrayRef proxies; // Reference to a dictionary that is released by the caller
;
void resultCallback(void* client, CFArrayRef proxies, CFErrorRef error)
// Error handling removed for brevity
if (CFTypeRef* resultPtr = (CFTypeRef*) client)
*resultPtr = CFRetain(proxies);
CFRunLoopStop(CFRunLoopGetCurrent());
// Provided PACRequestInfo is created on the stack by the caller
void doPACRequest(const PACRequestInfo& info)
CFTypeRef result = nullptr;
CFStreamClientContext context = 0, &result, nullptr, nullptr, nullptr ;
// Scoped ptr not shown but just calls CFRelease on destruction
CFScopedPtr<CFRunLoopSourceRef> runLoopSource(CFNetworkExecuteProxyAutoConfigurationURL(info.scriptURL, info.url, resultCallback, &context));
if (runLoopSource)
const static CFStringRef kPrivateRunLoopMode = CFSTR("myprivateloop");
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kPrivateRunLoopMode);
CFRunLoopRunInMode(kPrivateRunLoopMode, 1.0e10, false);
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoopSource, kPrivateRunLoopMode);
if (result && CFGetTypeID(result) == CFArrayGetTypeID())
CFArrayRef resultArray = (CFArrayRef) result;
CFArrayAppendArray(info.proxies, resultArray, CFRangeMake(0, CFArrayGetCount(resultArray)));
// Retain was called on this value during ResultCallback.
if (result)
CFRelease(result);
memory-leaks proxy cfnetwork cfrunloop
add a comment |
I am using CFNetwork APIs to detect OS proxy settings. My setup is heavily based on this:
https://github.com/adobe/chromium/blob/master/net/proxy/proxy_resolver_mac.cc
which is pretty much the same as this:
https://developer.apple.com/library/archive/samplecode/CFProxySupportTool/Introduction/Intro.html
I use CFNetworkCopyProxiesForURL to get the list of proxies, and for the PAC types, use CFNetworkExecuteProxyAutoConfigurationURL to fetch and execute the PAC script, immediately running the run loop on the current thread, which is already not on the ui thread.
This all works properly, and I have carefully combed through making sure that I am following the create rule to properly release results. However, when using Xcode instruments, I'm seeing that std::shared_ptrs to PAC::PACClient are leaked by _CFNetworkExecuteProxyAutoConfigurationURLDelegated. Since that object is never exposed to me, I'm not sure how I can control its release, but it is leaking. This is only an issue with fetching PAC files, explicit proxies do not leak. I have tried adding redundant CFRelease calls on all the CFDictionaries and such exposed to me to see if something was being over retained, but it didn't make a difference to the PACClient leak.
This is on Mac in a cpp file, not objective C, in a project with ARC on.
Has anyone encountered this leak and know how to prevent it?
Below is the snippet that executes the lookup, which is all the same steps from the above projects.
struct PACRequestInfo
CFURLRef url; // Caller gets this from a dictionary, doesn't need release
CFURLRef scriptURL; // Caller gets this from a dictionary, doesn't need release
CFMutableArrayRef proxies; // Reference to a dictionary that is released by the caller
;
void resultCallback(void* client, CFArrayRef proxies, CFErrorRef error)
// Error handling removed for brevity
if (CFTypeRef* resultPtr = (CFTypeRef*) client)
*resultPtr = CFRetain(proxies);
CFRunLoopStop(CFRunLoopGetCurrent());
// Provided PACRequestInfo is created on the stack by the caller
void doPACRequest(const PACRequestInfo& info)
CFTypeRef result = nullptr;
CFStreamClientContext context = 0, &result, nullptr, nullptr, nullptr ;
// Scoped ptr not shown but just calls CFRelease on destruction
CFScopedPtr<CFRunLoopSourceRef> runLoopSource(CFNetworkExecuteProxyAutoConfigurationURL(info.scriptURL, info.url, resultCallback, &context));
if (runLoopSource)
const static CFStringRef kPrivateRunLoopMode = CFSTR("myprivateloop");
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kPrivateRunLoopMode);
CFRunLoopRunInMode(kPrivateRunLoopMode, 1.0e10, false);
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoopSource, kPrivateRunLoopMode);
if (result && CFGetTypeID(result) == CFArrayGetTypeID())
CFArrayRef resultArray = (CFArrayRef) result;
CFArrayAppendArray(info.proxies, resultArray, CFRangeMake(0, CFArrayGetCount(resultArray)));
// Retain was called on this value during ResultCallback.
if (result)
CFRelease(result);
memory-leaks proxy cfnetwork cfrunloop
Seems like a lot of stuff leaking in CFNetwork. I have SocketStream, and here's another proxy-related issue.
– Sergei Ousynin
Jan 8 at 19:01
add a comment |
I am using CFNetwork APIs to detect OS proxy settings. My setup is heavily based on this:
https://github.com/adobe/chromium/blob/master/net/proxy/proxy_resolver_mac.cc
which is pretty much the same as this:
https://developer.apple.com/library/archive/samplecode/CFProxySupportTool/Introduction/Intro.html
I use CFNetworkCopyProxiesForURL to get the list of proxies, and for the PAC types, use CFNetworkExecuteProxyAutoConfigurationURL to fetch and execute the PAC script, immediately running the run loop on the current thread, which is already not on the ui thread.
This all works properly, and I have carefully combed through making sure that I am following the create rule to properly release results. However, when using Xcode instruments, I'm seeing that std::shared_ptrs to PAC::PACClient are leaked by _CFNetworkExecuteProxyAutoConfigurationURLDelegated. Since that object is never exposed to me, I'm not sure how I can control its release, but it is leaking. This is only an issue with fetching PAC files, explicit proxies do not leak. I have tried adding redundant CFRelease calls on all the CFDictionaries and such exposed to me to see if something was being over retained, but it didn't make a difference to the PACClient leak.
This is on Mac in a cpp file, not objective C, in a project with ARC on.
Has anyone encountered this leak and know how to prevent it?
Below is the snippet that executes the lookup, which is all the same steps from the above projects.
struct PACRequestInfo
CFURLRef url; // Caller gets this from a dictionary, doesn't need release
CFURLRef scriptURL; // Caller gets this from a dictionary, doesn't need release
CFMutableArrayRef proxies; // Reference to a dictionary that is released by the caller
;
void resultCallback(void* client, CFArrayRef proxies, CFErrorRef error)
// Error handling removed for brevity
if (CFTypeRef* resultPtr = (CFTypeRef*) client)
*resultPtr = CFRetain(proxies);
CFRunLoopStop(CFRunLoopGetCurrent());
// Provided PACRequestInfo is created on the stack by the caller
void doPACRequest(const PACRequestInfo& info)
CFTypeRef result = nullptr;
CFStreamClientContext context = 0, &result, nullptr, nullptr, nullptr ;
// Scoped ptr not shown but just calls CFRelease on destruction
CFScopedPtr<CFRunLoopSourceRef> runLoopSource(CFNetworkExecuteProxyAutoConfigurationURL(info.scriptURL, info.url, resultCallback, &context));
if (runLoopSource)
const static CFStringRef kPrivateRunLoopMode = CFSTR("myprivateloop");
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kPrivateRunLoopMode);
CFRunLoopRunInMode(kPrivateRunLoopMode, 1.0e10, false);
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoopSource, kPrivateRunLoopMode);
if (result && CFGetTypeID(result) == CFArrayGetTypeID())
CFArrayRef resultArray = (CFArrayRef) result;
CFArrayAppendArray(info.proxies, resultArray, CFRangeMake(0, CFArrayGetCount(resultArray)));
// Retain was called on this value during ResultCallback.
if (result)
CFRelease(result);
memory-leaks proxy cfnetwork cfrunloop
I am using CFNetwork APIs to detect OS proxy settings. My setup is heavily based on this:
https://github.com/adobe/chromium/blob/master/net/proxy/proxy_resolver_mac.cc
which is pretty much the same as this:
https://developer.apple.com/library/archive/samplecode/CFProxySupportTool/Introduction/Intro.html
I use CFNetworkCopyProxiesForURL to get the list of proxies, and for the PAC types, use CFNetworkExecuteProxyAutoConfigurationURL to fetch and execute the PAC script, immediately running the run loop on the current thread, which is already not on the ui thread.
This all works properly, and I have carefully combed through making sure that I am following the create rule to properly release results. However, when using Xcode instruments, I'm seeing that std::shared_ptrs to PAC::PACClient are leaked by _CFNetworkExecuteProxyAutoConfigurationURLDelegated. Since that object is never exposed to me, I'm not sure how I can control its release, but it is leaking. This is only an issue with fetching PAC files, explicit proxies do not leak. I have tried adding redundant CFRelease calls on all the CFDictionaries and such exposed to me to see if something was being over retained, but it didn't make a difference to the PACClient leak.
This is on Mac in a cpp file, not objective C, in a project with ARC on.
Has anyone encountered this leak and know how to prevent it?
Below is the snippet that executes the lookup, which is all the same steps from the above projects.
struct PACRequestInfo
CFURLRef url; // Caller gets this from a dictionary, doesn't need release
CFURLRef scriptURL; // Caller gets this from a dictionary, doesn't need release
CFMutableArrayRef proxies; // Reference to a dictionary that is released by the caller
;
void resultCallback(void* client, CFArrayRef proxies, CFErrorRef error)
// Error handling removed for brevity
if (CFTypeRef* resultPtr = (CFTypeRef*) client)
*resultPtr = CFRetain(proxies);
CFRunLoopStop(CFRunLoopGetCurrent());
// Provided PACRequestInfo is created on the stack by the caller
void doPACRequest(const PACRequestInfo& info)
CFTypeRef result = nullptr;
CFStreamClientContext context = 0, &result, nullptr, nullptr, nullptr ;
// Scoped ptr not shown but just calls CFRelease on destruction
CFScopedPtr<CFRunLoopSourceRef> runLoopSource(CFNetworkExecuteProxyAutoConfigurationURL(info.scriptURL, info.url, resultCallback, &context));
if (runLoopSource)
const static CFStringRef kPrivateRunLoopMode = CFSTR("myprivateloop");
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kPrivateRunLoopMode);
CFRunLoopRunInMode(kPrivateRunLoopMode, 1.0e10, false);
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoopSource, kPrivateRunLoopMode);
if (result && CFGetTypeID(result) == CFArrayGetTypeID())
CFArrayRef resultArray = (CFArrayRef) result;
CFArrayAppendArray(info.proxies, resultArray, CFRangeMake(0, CFArrayGetCount(resultArray)));
// Retain was called on this value during ResultCallback.
if (result)
CFRelease(result);
memory-leaks proxy cfnetwork cfrunloop
memory-leaks proxy cfnetwork cfrunloop
asked Nov 13 '18 at 23:10
ManeugeantManeugeant
63
63
Seems like a lot of stuff leaking in CFNetwork. I have SocketStream, and here's another proxy-related issue.
– Sergei Ousynin
Jan 8 at 19:01
add a comment |
Seems like a lot of stuff leaking in CFNetwork. I have SocketStream, and here's another proxy-related issue.
– Sergei Ousynin
Jan 8 at 19:01
Seems like a lot of stuff leaking in CFNetwork. I have SocketStream, and here's another proxy-related issue.
– Sergei Ousynin
Jan 8 at 19:01
Seems like a lot of stuff leaking in CFNetwork. I have SocketStream, and here's another proxy-related issue.
– Sergei Ousynin
Jan 8 at 19:01
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53290871%2fleak-when-calling-cfnetworkexecuteproxyautoconfigurationurl-on-mac%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53290871%2fleak-when-calling-cfnetworkexecuteproxyautoconfigurationurl-on-mac%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Seems like a lot of stuff leaking in CFNetwork. I have SocketStream, and here's another proxy-related issue.
– Sergei Ousynin
Jan 8 at 19:01