Can't debug memory leak

Hi, im making a daemon swift app for macos that uses the content filter network extension. When i run the app i see the following leak in Instruments.
Code Block
2021-03-08 15:58:54.943753-0300 mhunt[23320:342851] [] nw_parameters_copy_default_protocol_stack called with null parameters
2021-03-08 15:58:54.950468-0300 mhunt[23320:342851] [] nw_parameters_copy_default_protocol_stack called with null parameters, dumping backtrace:
[x86_64] libnetcore-2288.80.2
0 libnetwork.dylib 0x00007fff247c82f8 __nw_create_backtrace_string + 120
1 libnetwork.dylib 0x00007fff242bb69b nw_parameters_copy_default_protocol_stack + 251
2 libnetwork.dylib 0x00007fff242dea0e nw_socket_connect + 1550
3 libnetworkextension.dylib 0x00007fff300c6102 ne_filter_protocol_connect + 396
4 libnetworkextension.dylib 0x00007fff300c73dc ne_filter_process_verdict + 1616
5 libnetworkextension.dylib 0x00007fff300cb5f7 __ne_filter_data_protocol_send_new_flow_block_invoke.65 + 148
6 libdispatch.dylib 0x000000010b5e8e78 _dispatch_call_block_and_release + 12
7 libdispatch.dylib 0x000000010b5ea0b0 _dispatch_client_callout + 8
8 libdispatch.dylib 0x000000010b5f406a _dispatch_workloop_invoke + 3277
9 libdispatch.dylib 0x000000010b600217 _dispatch_workloop_worker_thread + 1675
10 libsystem_pthread.dylib 0x000000010b693b15 _pthread_wqthread + 314
11 libsystem_pthread.dylib 0x000000010b692ae3 start_wqthread + 15

I have no idea how to debug this. As you can see on the log it says "libnetworkextension" so i thought i might have something to do with the network extension but the leak ocurrs even when the NE is not running.
I tried looking at the memory graph but when i go to click on the memory address that has the leak all i see is an icon of "OS_dispatch_group".
I know this might be not enough information to help me debug this so if you need anything else just let me know.
UPDATE:
I think i know what part of my code is causing this but im not sure why.
Basically my daemon makes a request to an api every 3 minutes and i think that request is causing this leak. The request is done using Alamofire. Here is the code:
Code Block      
// Here i schedule the timer for the request
 let timer = Timer.scheduledTimer(withTimeInterval: 180, repeats: true) { _ in
      make_request()
 }
 timer.fire()


This is what gets executed inside of the make_request func. Both the body, url and headers of the request are not relevant as they are not whats causing the problem.
Code Block
   private static func post(path:String, body: Dictionary<String,Any>, completion: @escaping (JSON?, Bool) -> Void) {
    AF.request(basePath + path, method:.post, parameters: body, encoding: JSONEncoding.default, headers: headers(), interceptor: CustomInterceptor(), requestModifier: {$0.timeoutInterval = 13}).validate().responseJSON { response in
      switch response.result {
      case .success(_):
        let jsonData = try! JSON(data:response.data!)
        completion(jsonData, true)
      case .failure(let error):
        switch error {
        case .sessionTaskFailed(let urlError as URLError) where urlError.code == .timedOut:
          print("Error - No api connection")
        default:
          print(error.errorDescription!)
        }
        completion(nil, false)
      }
    }
  }

If this is the part of your code that is producing the memory leak then try to moving it out to an isolated context, like a regular macOS app, and try running it from there. This should make debugging this code and profiling it in Instruments a lot easier. It should also reduce the surface area of other code involved for debugging.

From there take a look at what is being retained in the timer closure as your code runs and see what remains in persistent memory column over time. This should at least point you in the right direction on how to resolve this.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
I have stripped everything out of the app. This is literally all the app does. I am profiling it in Instruments and sometimes 30 min goes by and then the leak happens. Unfortunately Instruments doesn't give me a lot of info as shown in the log in my first post.

BTW do you think this is the correct approach to making requests in the background? I mean is there anything else recommended other than a Timer?
I think the Timer is what is causing the leak, as Matt said. I will try to implement a DispatchSource timer to run on a background queue. I'll post the result when im done.

UPDATE:
I made this simple method but the Timer doesnt execute when i call it from AppDelegates applicationDidFinishLaunching. Why is that?

Code Block    
func timer(){
    let timer = DispatchSource.makeTimerSource(flags: [], queue: queue)
    timer!.schedule(deadline: .now(), repeating: .seconds(5))
    timer!.setEventHandler {
      print("Hello")
    }
 
    timer!.resume()
}
     


I finally got DispatchSource Timer to work but the leak still continues. Another weird thing is that even though Instruments shows that there is a leak the memory usage of the app stays the same for hours so maybe the leak is not harmful ?
I will investigate if the fact that my post method is static has anything to do with the leak.
Ok last one.
I have set the timer to repeat every 10 seconds for the sake of testing. I have noticed in Instruments using Time Profiler that every time i make a request, more and more threads keep appearing and they dont go away so i think i may be on to something.
Im gonna be openning a TSI

I have noticed in Instruments using Time Profiler that every time i make a request, more and more threads keep appearing and they dont go away so i think i may be on to something.

I would try to move away from the Timer as it does seem to be persisting your objects on the heap.

Im gonna be openning a TSI

Okay, I will keep a look out for it.


Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Can't debug memory leak
 
 
Q