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

[CLIENT-2887] Fix aerospike.Client() segfaulting when it fails to connect #608

Merged
merged 3 commits into from
May 9, 2024

Conversation

juliannguyen4
Copy link
Collaborator

@juliannguyen4 juliannguyen4 commented Apr 26, 2024

How seg fault occurs

When aerospike.Client(config) is called, where config has a host / port that fails to connect:

  1. tp_new to create a new aerospike.Client object in Python. This presumably creates a new reference to the aerospike.Client object
  2. AerospikeClient_Type_Init() (tp_init) initializes theaerospike.Client object in Python, populates a C client config struct using the Python client's config dictionary, then creates a new C client using self->as = aerospike_new(&config);. Fail to connect, so destroy C client using aerospike_destroy(self->as);
  3. In Python, no reference to the aerospike.Client object exists anymore, so AerospikeClient_Type_Dealloc() (tp_dealloc) is called
  4. AerospikeClient_Type_Dealloc() calls aerospike_destroy() again on the same C client, causing a double free (seg fault)

Fix

In AerospikeClient_Type_Init(), if C client fails to connect, don't destroy it and let AerospikeClient_Type_Dealloc() handle it later.

Implications of this fix

aerospike.client(config) code must be changed to avoid a memory leak

AerospikeClient_New() is the Python client C code for aerospike.client(config). This is the main way to create a client, rather than aerospike.Client(config). aerospike.client(config) calls in this order:

  • AerospikeClient_Type.tp_new() to create the aerospike.Client object
  • AerospikeClient_Type.tp_init() to initialize the aerospike.Client object.
  • If tp_init() fails (i.e fails to connect), AerospikeClient_Type.tp_free() destroys the aerospike.Client object.

After this PR's changes, when the client fails to connect with aerospike.client(config), AerospikeClient_New() must find another way to destroy the C client since tp_init no longer does it. tp_dealloc destroys both the C client and Python client, so we replace tp_free() with that.

Valgrind

Dev: https://github.com/aerospike/aerospike-client-python/actions/runs/8914308860/job/24481631213
This branch: https://github.com/aerospike/aerospike-client-python/actions/runs/8913166351/job/24478118908

No new memory errors and there are less memory leaks in this branch

Build wheels all passes except for noise: https://github.com/aerospike/aerospike-client-python/actions/runs/9008696941

@codecov-commenter
Copy link

codecov-commenter commented Apr 26, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 81.36%. Comparing base (b80723d) to head (50f6d3a).
Report is 3 commits behind head on dev.

Additional details and impacted files
@@           Coverage Diff           @@
##              dev     #608   +/-   ##
=======================================
  Coverage   81.35%   81.36%           
=======================================
  Files         100      100           
  Lines       15355    15355           
=======================================
+ Hits        12492    12493    +1     
+ Misses       2863     2862    -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@juliannguyen4 juliannguyen4 marked this pull request as ready for review May 8, 2024 22:05
Copy link
Contributor

@justinlee-aerospike justinlee-aerospike left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes look good

@juliannguyen4 juliannguyen4 merged commit 7495e35 into dev May 9, 2024
147 of 151 checks passed
@juliannguyen4 juliannguyen4 deleted the CLIENT-2887-client-constructor-segfault branch May 9, 2024 19:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants