Skip to content
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

Memory release issue for released certificate #2238

Closed
sridevi-15 opened this issue Nov 27, 2018 · 3 comments

Comments

@sridevi-15
Copy link

commented Nov 27, 2018

Environment:

  • Version: any 2.0
  • Client OS: iOS
  • Sync-gateway version : 2.1.0

Steps to reproduce :

  1. Set up sync-gateways with ssl enabled.
  2. Create 2 DBs in 2 SGS and Create docs in CBL
    2. Set up 1 SG with revs limit 30 and SG2 with revs limit 25.
    3. Do push replication to two SGS(each DB
    to each SG).
    4. Do updates on CBL for 35 times.
    5. Continue push replication to SGs
    6. Verify that revs maintained on two SGS according to revs_limit.
    7. exchange DBs of SG and do push replication.
    8. Verify that revs maintained on two SGS according to revs_limit.

Result :

Test works fine. While cleaning up memory at the end of the test, app crashes

logs:

(lldb) bt
* thread #19, queue = 'com.apple.root.default-qos', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x000000010a1065e2 libswiftCore.dylib`swift_unknownRelease + 34
    frame #1: 0x0000000107ba5250 CouchbaseLiteSwift`outlined destroy of SecCertificateRef? at <compiler-generated>:0
    frame #2: 0x0000000107ba51ec CouchbaseLiteSwift`ReplicatorConfiguration.deinit(self=<unavailable>) at ReplicatorConfiguration.swift:0
    frame #3: 0x0000000107ba52b9 CouchbaseLiteSwift`ReplicatorConfiguration.__deallocating_deinit(self=<unavailable>) at ReplicatorConfiguration.swift:0
    frame #4: 0x000000010a0c8a40 libswiftCore.dylib`_swift_release_dealloc + 16
    frame #5: 0x000000010a0bce4b libswiftCore.dylib`swift_arrayDestroy + 59
    frame #6: 0x0000000109e77e26 libswiftCore.dylib`Swift._TypedNativeDictionaryStorage.deinit + 262
    frame #7: 0x0000000109e79a79 libswiftCore.dylib`Swift._HashableTypedNativeDictionaryStorage.__deallocating_deinit + 9
    frame #8: 0x000000010a0c8a40 libswiftCore.dylib`_swift_release_dealloc + 16
    frame #9: 0x0000000109e67fe1 libswiftCore.dylib`Swift.Dictionary.removeAll(keepingCapacity: Swift.Bool) -> () + 1025
  * frame #10: 0x00000001076fa8c7 CBLTestServer-iOS`Memory.flushMemory(self=0x0000600001bb07e0) at Memory.swift:72
    frame #11: 0x0000000107706a28 CBLTestServer-iOS`closure #1 in Server.init(request=0x00006000022ec580, self=0x0000600002eec820) at Server.swift:117
    frame #12: 0x000000010770bf7c CBLTestServer-iOS`partial apply for closure #1 in Server.init() at <compiler-generated>:0
    frame #13: 0x000000010770c002 CBLTestServer-iOS`thunk for @escaping @callee_guaranteed (@guaranteed GCDWebServerRequest) -> (@owned GCDWebServerResponse?) at <compiler-generated>:0
    frame #14: 0x000000010766755f CBLTestServer-iOS`__79-[GCDWebServer(.block_descriptor=0x0000600001bbb330, request=0x00006000022ec580, completionBlock=0x00000001076524f0) addDefaultHandlerForMethod:requestClass:processBlock:]_block_invoke at GCDWebServer.m:874
    frame #15: 0x0000000107659582 CBLTestServer-iOS`-[GCDWebServerConnection(self=0x0000600003ee1ce0, _cmd="processRequest:completion:", request=0x00006000022ec580, completion=0x00000001076524f0) processRequest:completion:] at GCDWebServerConnection.m:786
    frame #16: 0x00000001076524ba CBLTestServer-iOS`-[GCDWebServerConnection _startProcessingRequest](self=0x0000600003ee1ce0, _cmd="_startProcessingRequest") at GCDWebServerConnection.m:143
    frame #17: 0x00000001076535ac CBLTestServer-iOS`-[GCDWebServerConnection _readBodyWithLength:initialData:](self=0x0000600003ee1ce0, _cmd="_readBodyWithLength:initialData:", length=0, initialData=2 bytes) at GCDWebServerConnection.m:253
    frame #18: 0x0000000107654a9f CBLTestServer-iOS`__45-[GCDWebServerConnection _readRequestHeaders]_block_invoke(.block_descriptor=0x0000600001b2c240, extraData=2 bytes) at GCDWebServerConnection.m:345
    frame #19: 0x0000000107656098 CBLTestServer-iOS`__64-[GCDWebServerConnection(.block_descriptor=0x000060000005c940, success=YES) readHeaders:withCompletionBlock:]_block_invoke at GCDWebServerConnection.m:472
    frame #20: 0x00000001076558f6 CBLTestServer-iOS`__68-[GCDWebServerConnection(.block_descriptor=0x000060000005c440, buffer=0x000060000005a540, error=0) readData:withLength:completionBlock:]_block_invoke at GCDWebServerConnection.m:440
    frame #21: 0x000000010ab1705b libdispatch.dylib`__dispatch_read_block_invoke_2.53 + 39
    frame #22: 0x000000010aaec5d1 libdispatch.dylib`_dispatch_call_block_and_release + 12
    frame #23: 0x000000010aaed63e libdispatch.dylib`_dispatch_client_callout + 8
    frame #24: 0x000000010aafe209 libdispatch.dylib`_dispatch_root_queue_drain + 832
    frame #25: 0x000000010aafe9cd libdispatch.dylib`_dispatch_worker_thread2 + 130
    frame #26: 0x000000010aed9169 libsystem_pthread.dylib`_pthread_wqthread + 1387
    frame #27: 0x000000010aed8be9 libsystem_pthread.dylib`start_wqthread + 13
(lldb) 

sg config file:

{
    "interface":":4984",
    "adminInterface": "0.0.0.0:4985",
    "maxIncomingConnections": 0,
    "maxCouchbaseConnections": 16,
    "maxFileDescriptors": 90000,
    "slowServerCallWarningThreshold": 500,
    "compressResponses": false,
    "logging": {"debug": {"enabled": true} },
    "cluster_config": {
        "server":"http://192.168.33.10:8091",
        "data_dir":".",
        "bucket":"data-bucket-1",
        "username":"data-bucket-1",
        "password": "password"
    },
    "SSLCert": "sg_cert.pem",
    "SSLKey": "sg_privkey.pem",
    "databases":{
        "sg_db1":{
            
            "allow_conflicts": false,
            
            
            "num_index_replicas": 0,
            "server":"http://192.168.33.10:8091",
            "bucket":"data-bucket-1",
            "username":"data-bucket-1",
            "password": "password",
            "channel_index":{
                "server":"http://192.168.33.10:8091",
                "bucket":"index-bucket-1",
                "username":"index-bucket-1",
                "password": "password",
                "writer":false
            }
        },
        "sg_db2":{
            
            
            "num_index_replicas": 0,

            "server":"http://192.168.33.10:8091",
            "bucket":"data-bucket-2",
            "username":"data-bucket-2",
            "password": "password",
            "allow_conflicts": false,
            
            "channel_index":{
                "server":"http://192.168.33.10:8091",
                "bucket":"index-bucket-2",
                "username":"index-bucket-2",
                "password": "password",
                "writer":false
            }
        }
    }
}

CBL client app code where exactly it fails

https://github.com/couchbaselabs/mobile-testkit/blob/master/CBLClient/Apps/CBLTestServer-iOS/CBLTestServer-iOS/Server/Memory.swift#L72
Fails at _memory.removeAll() inside flushMemory()

@pasin pasin added this to the Iridium milestone Nov 30, 2018

@sridevi-15

This comment has been minimized.

Copy link
Author

commented Dec 6, 2018

@jayahariv , this is the command and the test which can be reproducible with above steps.

pytest -s -rsx -k test_multiple_sgs_with_differrent_revs_limit --timeout 1800 --liteserv-version=2.1.3-5 --liteserv-host=localhost --liteserv-port=8080 --no-conflicts --sg-ssl --sync-gateway-version=2.1.1 --mode=cc --server-version=5.5.0-2473 --liteserv-platform=ios --create-db-per-test=cbl-test testsuites/CBLTester/topology_specific_tests/multiple_sync_gateways

This needs alteast 2 to 3 VMs. You need to copy ansible.cfg.example to ansible.cfg.
You need to copy resources/pool.json.example to resources resources/pool.json and update ips of your VMS there.

Run python libraries/utilities/generate_clusters_from_pool.py

Then you can run the test. All this information there in ReadMe. Just want to let you know this is the set up needed. Let me know if you have any questions and need help in setting up

@pasin

This comment has been minimized.

Copy link
Contributor

commented Dec 6, 2018

@jayahariv Can the following scenario reproduce the issue?

  1. Create a replicator with a pinned SSL certificate.
  2. Make the replicator being released.
@jayahariv

This comment has been minimized.

Copy link
Contributor

commented Dec 6, 2018

@pasin I tried that, and no memory leak by itself, it shows the warning and crash when we test it through the pytest with Memory class used. I will try with the command, which Sridevi shared.

@sridevi-15 I will go through this, thanks.

jayahariv added a commit that referenced this issue Dec 7, 2018

Fixed #2238 : pinnedServerCertificate memory release issue (#2257)
* certificate was not retained in the constructor, but was doing in the setter method.
* setter method will be called, but when setting the configurtation through the replicator constructor, it was not retianing the certificate, and get deallocated when the allocated configuration object is automatically removed.

@jayahariv jayahariv removed the ready label Dec 7, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.