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

Fix/SDL memory leaks #41

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open

Fix/SDL memory leaks #41

wants to merge 8 commits into from

Conversation

SNiukalov
Copy link

@SNiukalov SNiukalov commented May 26, 2020

Fixes #Jira task

This PR is ready for review.

Risk

This PR makes no API changes.

Testing Plan

ATF scripts & Valgrind

Memory Leaks Report

Summary

Fix memory leaks in sdl and unit tests

CLA

@SNiukalov SNiukalov changed the title Fix/Sdl memory leaks Fix/SDL memory leaks May 26, 2020
@LuxoftAKutsan
Copy link

Could you please attach information about leaks?
Statistics would be good.

@@ -128,8 +128,8 @@ class MobileMessageHandlerTest : public testing::Test {

// Act
size_t payload_size = data.size();
Message* message = HandleIncomingMessage(
protocol_version, json_plus_binary_data, payload_size);
const auto message = std::shared_ptr<Message>(HandleIncomingMessage(

Choose a reason for hiding this comment

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

@SNiukalov Can't see any sharing here. What is teh reason to create shared_ptr?

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
Fixed in:be4a738

@@ -148,8 +148,8 @@ class MobileMessageHandlerTest : public testing::Test {
// Arrange
size_t payload_size = data.size();
size_t full_data_size = data.size() + PROTOCOL_HEADER_V2_SIZE;
Message* message =
HandleIncomingMessage(protocol_version, data, payload_size);
const auto message = std::shared_ptr<Message>(

Choose a reason for hiding this comment

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

@SNiukalov Can't see any sharing here. What is teh reason to create shared_ptr?

Copy link
Author

Choose a reason for hiding this comment

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

@@ -197,8 +197,8 @@ class MobileMessageHandlerTest : public testing::Test {
MobileMessage message_to_send = CreateMessageForSending(
protocol_version, function_id, correlation_id, connection_key, data);
// Act
RawMessage* result_message =
MobileMessageHandler::HandleOutgoingMessageProtocol(message_to_send);
std::shared_ptr<RawMessage> result_message(

Choose a reason for hiding this comment

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

@SNiukalov Can't see any sharing here. What is the reason to create shared_ptr?

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
Fixed in:be4a738

@@ -233,13 +233,15 @@ class MobileMessageHandlerTest : public testing::Test {
data,
bin_dat);
// Act
RawMessage* result_message =
MobileMessageHandler::HandleOutgoingMessageProtocol(message_to_send);
std::shared_ptr<RawMessage> result_message(

Choose a reason for hiding this comment

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

@SNiukalov Can't see any sharing here. What is the reason to create shared_ptr?

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
Fixed in:be4a738

std::vector<uint8_t> full_data = joiner<std::vector<uint8_t> >(
binary_header, binary_header + PROTOCOL_HEADER_V2_SIZE, data);
size_t full_size =
sizeof(uint8_t) * full_data.size() + bin_dat->size() * sizeof(uint8_t);

delete bin_dat;

Choose a reason for hiding this comment

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

@SNiukalov Why do you use heap? Is it possible to use stack for bin_dat? ?

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
Fixed in:be4a738

@@ -121,10 +121,10 @@ TEST(MobileMessageHandlerTestV1Test,
message->set_json_message(data_json);
message->set_connection_key(connection_key_p1);

RawMessage* ptr =
MobileMessageHandler::HandleOutgoingMessageProtocol(message);
std::shared_ptr<RawMessage> ptr(

Choose a reason for hiding this comment

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

@SNiukalov Can't see any sharing here. What is the reason to create shared_ptr?

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
Fixed in:be4a738

@@ -52,6 +52,52 @@ using ::testing::Return;
using ::testing::ReturnPointee;
using ::testing::ReturnRef;

ResumptionDataTest::~ResumptionDataTest() {
for (auto& submenu : test_submenu_map) {
delete submenu.second;

Choose a reason for hiding this comment

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

@SNiukalov why do we dlete only second item? Don't we clear the entire map?

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
Fixed in:be4a738

menu_title_ = new sm::SmartObject(sm_title);

if (menu_icon_) {
delete menu_icon_;

Choose a reason for hiding this comment

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

@SNiukalov Smart pointers for all such items?

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
No, because this field we using int the ReturnPointee

std::swap(delegates_queue_, empty_queue);
delegates_queue_lock_.Release();
do {
auto delegate = empty_queue.front();

Choose a reason for hiding this comment

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

@SNiukalov The name looks bad. How can we pop and delete something from an empty queue? ))

Copy link
Author

Choose a reason for hiding this comment

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

{
std::shared_ptr<AsyncRunner> async_runner =
std::make_shared<AsyncRunner>("test");
async_runner->Stop();
async_runner->AsyncRun(&mock_thread_delegate);
async_runner->AsyncRun(mock_thread_delegate);

Choose a reason for hiding this comment

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

@SNiukalov Is Async_runner responsible for thread delegate destruction?

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
Yes, Async_runner responsible for thread delegate destruction

@SNiukalov
Copy link
Author

SNiukalov commented Jun 4, 2020

/**
* @bref clearDelegateQueue delete leftover delegates in the queue
*/
void clearDelegateQueue();
Copy link

@AByzhynar AByzhynar Jun 9, 2020

Choose a reason for hiding this comment

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

@SNiukalov Wrong naming(Coding style). The function name should start with a capital letter

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
Fixed in:dff6e3e

if (!delegates_queue_.empty()) {
std::queue<threads::ThreadDelegate*> queue_to_delete;
delegates_queue_lock_.Acquire();
std::swap(delegates_queue_, queue_to_delete);

Choose a reason for hiding this comment

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

@SNiukalov No appropriate header files included

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
Fixed in:dff6e3e

@@ -88,6 +92,22 @@ void AsyncRunner::AsyncRunnerDelegate::waitForDelegate() {
}
}

void AsyncRunner::AsyncRunnerDelegate::clearDelegateQueue() {
if (!delegates_queue_.empty()) {
std::queue<threads::ThreadDelegate*> queue_to_delete;

Choose a reason for hiding this comment

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

@SNiukalov No appropriate header files included

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
Header file for the std::queue present in async_runner.h

Copy link

@AByzhynar AByzhynar Jun 9, 2020

Choose a reason for hiding this comment

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

@SNiukalov It does not matter. You define the entity here - so don't create implicit dependency from header file. Include all headers explicitly

Copy link
Author

@SNiukalov SNiukalov Jun 9, 2020

Choose a reason for hiding this comment

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

@AByzhynar
I don’t understand why we need duplicates.
This inclusion is present in the header file and also defines the entity.
If you change this header, we will still be forced to change the code in this place. Because it depends on the member of the delegates_queue_ class.
What is the meaning of this inclusion then?

Copy link

@AByzhynar AByzhynar Jun 9, 2020

Choose a reason for hiding this comment

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

@SNiukalov You defining implicit dependency. This is BAD. You will change something in header e.g. change container from queue to list. What you get is CC file can't be compiled.
Read https://github.com/smartdevicelink/sdl_core/wiki/SDL-Coding-Style-Guide
Don't create dependencies between independent things.

Copy link
Author

@SNiukalov SNiukalov Jun 9, 2020

Choose a reason for hiding this comment

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

@AByzhynar
Yes, if change container from queue to list. What you get is CC file can't be compiled.
And if make include to cc I get is CC file can't be compiled. :) Because deffirents types :)

Fixed in:e62a8eb & b985f83

@@ -90,7 +90,7 @@ TEST(ScopeGuardTest, CallObjectFunctionWithParam) {
TEST(ScopeGuardTest, DismissCallFreeFunctionWithParam) {
{
call_with_param_count = 0;
char* ptr = new char;
char* ptr = const_cast<char*>("dealloc is not called");

Choose a reason for hiding this comment

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

@SNiukalov Can you please explain this magic?

Copy link
Author

Choose a reason for hiding this comment

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

@AByzhynar
In this case, we check that the CallFreeFunction will never be called and the memory will not be freed.
But we pass the pointer from the heap and make a memory leak.
I change this behavior and leave a reminder with text: dealloc not called

Copy link

@LuxoftAKutsan LuxoftAKutsan left a comment

Choose a reason for hiding this comment

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

👍

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.

6 participants