-
Notifications
You must be signed in to change notification settings - Fork 150
Fix memory leak in xml_wrapper #4647
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
Conversation
|
Thank you for your contribution @kysucix! We will review the pull request and get back to you soon. |
|
@kysucix Do you still see memory leak issues in the latest release? If so, can you share a code snippet that can reproduce the leak issue? |
|
Keeping it in draft mode as a test in win2022 is failing. |
|
I can confirm that the leak is still present on latest release and latest master version (b8e6aa1). |
|
This is enough to trigger a memory leak in |
|
Thanks @kysucix . We'll take some time to test the repro and review your PR. |
|
@kysucix I had a quick glance at the changes in this PR. It seems to me all of proposed changes are equivalent to what it is in main branch, like using smart points for reader/writer context rather than raw void points. |
|
In the patch it's using |
|
also |
| explicit XmlNode( | ||
| XmlNodeType type, | ||
| std::string name = std::string(), | ||
| std::string value = std::string()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| std::string value = std::string()) | |
| std::string value = {})) |
Q2:
Why are you using a copy constructor for name and value and then moving them to Name? Why not pass nme and value as const& and then construct Name and Value from the reference?
In other words, something like:
explicit XmlNode(
XmlNodeType type,
std::string const& name={},
std::string const& type={}) : Type(type), Name(name), Value(value) {}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed it's better to pass arguments as const&.
I'll fix it thanks!
Bear in mind that I'm porting a fix from https://github.com/ClickHouse/azure-sdk-for-cpp and it's not my code :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LarryOsterman About passing by value or reference, if you look at sdk/storage/azure-storage-common/src/xml_wrapper.cpp, at all of calling sites of this constructor, we pass by right values (e.g. XmlNode(type, std::move(name), std::move(value))).
So if the constructor argument is passed by value, the actual string data is first moved from the local variable of calling site, then moved to XmlNode private members, there's no copy here.
If by const reference, we'll need to make two copies.
There are a lot of discussions on stackoverflow regarding this topic, like https://stackoverflow.com/questions/4321305/best-form-for-constructors-pass-by-value-or-reference
| class XmlReader final { | ||
| public: | ||
| explicit XmlReader(const char* data, size_t length); | ||
| XmlReader(const char* data, size_t length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| XmlReader(const char* data, size_t length); | |
| XmlReader(uint8_t const* data, size_t length); |
Binary data should be std::uint8_t, not char - char should be reserved for characters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
XML data is seldom binary. It's usually printable strings. We should use char* instead of `uint8_t* in this case, shouldn't we?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is string data, it should be std::string. The incantation of pointer+length is normally used for binary data. If this is intended for signed 8 bit integers, you should add a comment explaining why this cannot be a std::string. Also why 8 bit signed integer is the correct representation of this data.
…rnal/xml_wrapper.hpp Co-authored-by: Larry Osterman <[email protected]>
…rnal/xml_wrapper.hpp Co-authored-by: Larry Osterman <[email protected]>
Even with
in current implementation, Anyway, I'll dig into it. What kind of leak sanitizer are you using? I'll try to reproduce. @kysucix |
|
Hi @kysucix i'm trying to repro this issue with below code #include <azure/storage/blobs.hpp>
#include <cstdio>
#include <iostream>
#include <stdexcept>
int main()
{
const static std::string ConnectionString = "";
using namespace Azure::Storage::Blobs;
int* unused_var = new int;
(void)unused_var;
const std::string containerName = "sample-container";
const std::string blobName = "sample-blob";
const std::string blobContent = "Hello Azure!";
auto containerClient
= BlobContainerClient::CreateFromConnectionString(ConnectionString, containerName);
containerClient.CreateIfNotExists();
for (int i =0 ; i < 10; ++i) {
auto blobClient= containerClient.GetAppendBlobClient("sample-blob-a-" + std::to_string(i));
blobClient.CreateIfNotExists();
}
for (int i = 0; i < 10; ++i) {
containerClient.ListBlobs();
}
return 0;
}The output is It can detect the leak I created on purpose to prove LeakSanitizer is correctly enabled, but cannot detect any leak from xml wrapper. |
|
Hi @kysucix. Thank you for your interest in helping to improve the Azure SDK experience and for your contribution. We've noticed that there hasn't been recent engagement on this pull request. If this is still an active work stream, please let us know by pushing some changes or leaving a comment. Otherwise, we'll close this out in 7 days. |
|
Hi @kysucix. Thank you for your contribution. Since there hasn't been recent engagement, we're going to close this out. Feel free to respond with a comment containing |
Backport memory fixes from https://github.com/ClickHouse/azure-sdk-for-cpp
This is effectively silencing address sanitizers warnings we've been observing.
Includes the following PRs:
ClickHouse#4
ClickHouse#5
ClickHouse#6
Pull Request Checklist
Please leverage this checklist as a reminder to address commonly occurring feedback when submitting a pull request to make sure your PR can be reviewed quickly:
See the detailed list in the contributing guide.