Closed sagunkho closed 3 months ago
Hi @sagunkho,
Could you please elaborate why do you think the leak is caused by ssl_ctx
? I can see some objects that look like allocated by OpenSSL in your dump, but they may be being kept alive by other components. Without knowing your application structure (i.e. without knowing how DatabaseProcess
and other objects are created and destroyed), I can't help much more.
I'd note that this pattern:
boost::asio::ssl::context _ssl_ctx{boost::asio::ssl::context::tls_client};
std::shared_ptr<boost::mysql::tcp_ssl_connection> _connection{nullptr};
Seems error-prone. The SSL context should be kept alive for the lifetime of the connection, at least, which this is not guaranteeing. If shared ownership semantics are needed, I suggest that you group these two into a struct
and create a shared_ptr
to that struct (which I think I already suggested in a previous issue).
If you're using Boost 1.85+ and you don't mind using experimental features, you might also consider using any_connection
, which takes care of the context creation for you.
https://github.com/horizonxyz/horizon/actions/runs/10269112883/job/28413796095#step:4:309
Is there some kind of cleanup that is required?
There shouldn't be. Let me have a look at your logs.
Which test is the one detecting the memory leak? Can't find the test name from the logs
This is the file that is causing the leak - https://github.com/horizonxyz/horizon/blob/concurrent-architecture-2/src/Tests/AuthServerTest.cpp
The initialize of DatabaseProcess is called here - https://github.com/horizonxyz/horizon/blob/825ecb6a323e0080c5f7278fd908052c9532ba00/src/Server/Common/Server.cpp#L299 And the initialize method definition is here - https://github.com/horizonxyz/horizon/blob/825ecb6a323e0080c5f7278fd908052c9532ba00/src/Server/Common/Server.cpp#L187
These are just the test files, there are the actual targets which are build and there is no memory dump from here. However, it is weird that this is happening in the test files. Auth, Zone, Char logs - https://github.com/horizonxyz/horizon/actions/runs/10269112883/job/28419790529 Thanks for taking a look.
I've been having a look and I'm still missing info to come to a conclusion. Which tool are you using to detect the leaks? If it's this one could you please follow the instructions and define _CRTDBG_MAP_ALLOC
in your debug builds so we can get a better understanding on where was the memory allocated?
Also, the log seems to contain an error line, which I'd say indicates lack of connectivity to the database in your test run. Does the leak report happen when no error is reported, too?
I'm using the standard MSVC built-in tool, if there is any. There is no special tool used. MSVC is used to compile. The errors are not detected in GCC and Clang.
https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail Virus-free.www.avast.com https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
On Wed, Aug 7, 2024 at 11:15 PM Anarthal (Rubén Pérez) < @.***> wrote:
I've been having a look and I'm still missing info to come to a conclusion. Which tool are you using to detect the leaks? If it's this one https://learn.microsoft.com/en-us/cpp/c-runtime-library/find-memory-leaks-using-the-crt-library?view=msvc-170 could you please follow the instructions and define _CRTDBG_MAP_ALLOC in your debug builds so we can get a better understanding on where was the memory allocated?
Also, the log seems to contain an error line, which I'd say indicates lack of connectivity to the database in your test run. Does the leak report happen when no error is reported, too?
— Reply to this email directly, view it on GitHub https://github.com/boostorg/mysql/issues/327#issuecomment-2274000611, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABBCGYZZUWI7S3TBQPK25ULZQJMKDAVCNFSM6AAAAABMB2MQHCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENZUGAYDANRRGE . You are receiving this because you were mentioned.Message ID: @.***>
I've been trying to fork your repo and reproduce the reported leak (https://github.com/anarthal/horizon/actions/runs/10300441653/job/28509832971) but I'm getting errors. Are you using self-hosted GitHub runners?
The problem here is that the failing build has a lot of complexity, with a lots of components involved. In order to investigate it, I need a minimum reproducible example, if possible only using Boost.MySQL and no other components. Otherwise, it's impossible to know where exactly the leak is coming from.
Hi Anarthal,
I've reverted the repo to the builds which are passing. The latest commit on that repository will be passing in a few hours. I am using self-hosted Github Runners.
https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail Virus-free.www.avast.com https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
On Thu, Aug 8, 2024 at 4:06 PM Anarthal (Rubén Pérez) < @.***> wrote:
I've been trying to fork your repo and reproduce the reported leak ( https://github.com/anarthal/horizon/actions/runs/10300441653/job/28509832971) but I'm getting errors. Are you using self-hosted GitHub runners?
The problem here is that the failing build has a lot of complexity, with a lots of components involved. In order to investigate it, I need a minimum reproducible example, if possible only using Boost.MySQL and no other components. Otherwise, it's impossible to know where exactly the leak is coming from.
— Reply to this email directly, view it on GitHub https://github.com/boostorg/mysql/issues/327#issuecomment-2275497634, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABBCGY72CNZLQKJ6XW2GJRTZQNC3DAVCNFSM6AAAAABMB2MQHCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENZVGQ4TONRTGQ . You are receiving this because you were mentioned.Message ID: @.***>
Please post a link to the build you're mentioning and to the code diff that fixes the problem - I may be able to provide further guidance.
This is the build -
Concurrent Architecture with Horizon New Design ·
@.*** (github.com)
https://github.com/horizonxyz/horizon/actions/runs/10299497300
Haven't found a fix yet so there's no code-diff. The build was earlier
failing because I was trying to provide shared libraries as an option in
configuring the project.
The library is statically linked now and not shared, there is no option to
link it as shared. It has nothing to do with the mysql memory leak problem.
The files are still the same, the code is still the same where the problem
generates. I had only reverted the code to
61fed78cd9eb5e6c612bb6f7ac0c42d8a6bc5d90
on branch
concurrent-architecture-2
.
Thanks for helping with the problem.
On Thu, Aug 8, 2024 at 9:34 PM Anarthal (Rubén Pérez) < @.***> wrote:
Please post a link to the build you're mentioning and to the code diff that fixes the problem - I may be able to provide further guidance.
— Reply to this email directly, view it on GitHub https://github.com/boostorg/mysql/issues/327#issuecomment-2276179865, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABBCGY6UDLGVDPQWDQP32H3ZQOJJXAVCNFSM6AAAAABMB2MQHCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENZWGE3TSOBWGU . You are receiving this because you were mentioned.Message ID: @.***>
https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail Virus-free.www.avast.com https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
I've finally found the tool you're using - it's a Boost.Test feature activated on MSVC debug builds that uses the CRT leak detector underneath.
We need to know where the allocations came from. Can you please issue a build defining the _CRTDBG_MAP_ALLOC
macro in all your translation units (as per these docs) and see if we get more info?
Thanks.
I've created a test case -
#include "Server/Auth/Auth.hpp"
#define BOOST_TEST_MODULE AuthServerTest
#include <boost/test/included/unit_test.hpp>
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
// One one test in this file as the server is a singleton and we can't have
multiple instances of it.
// If another test was created, the object would be destroyed and the
second test would fail / crash.
BOOST_AUTO_TEST_CASE(AuthServerTest)
{
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
try {
std::thread thread = std::thread([&]() {
sAuth->general_conf().set_test_run(TEST_RUN_MINIMAL);
sAuth->general_conf().set_config_file_path(
"config/auth-server.lua.dist");
sAuth->read_config();
set_shutdown_signal(SHUTDOWN_INITIATED);
sAuth->initialize();
});
thread.join();
} catch(std::length_error &e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
} catch(std::bad_alloc &e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
} catch(std::exception &e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
} catch(...) {
std::cerr << "Unknown exception caught." << std::endl;
}
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
_CrtDumpMemoryLeaks();
}
And within this, the following leak was dumped. Please see attached file.
https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail Virus-free.www.avast.com https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
On Fri, Aug 9, 2024 at 3:18 PM Anarthal (Rubén Pérez) < @.***> wrote:
I've finally found the tool you're using - it's a Boost.Test feature activated on MSVC debug builds https://live.boost.org/doc/libs/1_85_0/libs/test/doc/html/boost_test/utf_reference/rt_param_reference/detect_memory_leaks.html that uses the CRT leak detector https://learn.microsoft.com/en-us/cpp/c-runtime-library/find-memory-leaks-using-the-crt-library?view=msvc-170 underneath.
We need to know where the allocations came from. Can you please issue a build defining the _CRTDBG_MAP_ALLOC macro in all your translation units (as per these docs https://learn.microsoft.com/en-us/cpp/c-runtime-library/find-memory-leaks-using-the-crt-library?view=msvc-170) and see if we get more info?
Thanks.
— Reply to this email directly, view it on GitHub https://github.com/boostorg/mysql/issues/327#issuecomment-2277573559, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABBCGY4KP5BFYKXH2EIAQGLZQSF7BAVCNFSM6AAAAABMB2MQHCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDENZXGU3TGNJVHE . You are receiving this because you were mentioned.Message ID: @.***>
Okay, this didn't add any information. But that's because you defined _CRTDBG_MAP_ALLOC
after including your own headers, so any allocations made in files included before the macro was defined are probably not tracked. Also, Boost.Test will do _CrtDumpMemoryLeaks
for you. Doing it in your test case will report false positives, since there's memory that hasn't been released yet at that point.
My suggestion to move forward:
_CrtXXXXX
calls from your code._CRTDBG_MAP_ALLOC
first thing in your test. The easiest way to do it is to add a target_compile_definitions(you_executable PRIVATE _CRTDBG_MAP_ALLOC)
command in your CMake.Sorry that I didn't explain myself better in my previous post.
Regards, Ruben.
Thanks for the reply.
I added the target_compile_definitions
line to the cmake file and removed
the _Crt calls from the code. The output was similar and not any different.
*** No errors detected
Detected memory leaks!
Dumping objects ->
{16193} normal block at 0x000001DEC38A2E80, 3 bytes long.
Data: <> > 3E 1C 20
{14740} normal block at 0x000001DEC38A09B0, 448 bytes long.
Data: < \ l > 04 1C B4 05 C5 A2 9C B6 5C F1 A5 09 6C A1 C4 AE
{14739} normal block at 0x000001DEC38A07B0, 448 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{14738} normal block at 0x000001DEC38A06B0, 184 bytes long.
Data: < = > F0 3D D8 C1 DE 01 00 00 00 00 00 00 00 00 00 00
{14737} normal block at 0x000001DEC38A05B0, 184 bytes long.
Data: < U > 80 55 D9 C1 DE 01 00 00 00 00 00 00 00 00 00 00
{14735} normal block at 0x000001DEC38A04C0, 176 bytes long.
Data: < > B0 05 8A C3 DE 01 00 00 B0 06 8A C3 DE 01 00 00
{14734} normal block at 0x000001DEC1D44160, 296 bytes long.
Data: < > 00 00 00 00 00 00 00 00 20 B5 DC C1 DE 01 00 00
{14733} normal block at 0x000001DEC389B3E0, 40 bytes long.
Data: <@ A > 40 F0 D0 C1 DE 01 00 00 60 41 D4 C1 DE 01 00 00 {14730} normal block at 0x000001DEC38A02C0, 448 bytes long. Data: <F "D qD > 46 B3 22 44 E2 AA C3 09 CA 9F E0 A6 71 44 9A DC {14729} normal block at 0x000001DEC38A00C0, 448 bytes long. Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 {14728} normal block at 0x000001DEC389FD80, 184 bytes long. Data: < = > F0 3D D8 C1 DE 01 00 00 00 00 00 00 00 00 00 00 {14727} normal block at 0x000001DEC389FC80, 184 bytes long. Data: < U > 80 55 D9 C1 DE 01 00 00 00 00 00 00 00 00 00 00 {14725} normal block at 0x000001DEC389FB90, 176 bytes long. Data: < > 80 FC 89 C3 DE 01 00 00 80 FD 89 C3 DE 01 00 00 {14724} normal block at 0x000001DEC1D442D0, 296 bytes long. Data: < > 00 00 00 00 00 00 00 00 20 B5 DC C1 DE 01 00 00 {14723} normal block at 0x000001DEC389C8E0, 40 bytes long. Data: <@ B > 40 F0 D0 C1 DE 01 00 00 D0 42 D4 C1 DE 01 00 00 {14721} normal block at 0x000001DEC38950A0, 16 bytes long. Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 {14718} normal block at 0x000001DEC389F990, 448 bytes long. Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 {14717} normal block at 0x000001DEC389F890, 184 bytes long. Data: < U > 80 55 D9 C1 DE 01 00 00 00 00 00 00 00 00 00 00 {14716} normal block at 0x000001DEC389F690, 448 bytes long. Data: < 6 7\ { #A c m> A7 36 E1 AC 37 5C A1 7B 20 84 23 41 E3 63 05 6D {14715} normal block at 0x000001DEC389F490, 448 bytes long. Data: < > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 {14714} normal block at 0x000001DEC1D85890, 184 bytes long. Data: < = > F0 3D D8 C1 DE 01 00 00 00 00 00 00 00 00 00 00 {14713} normal block at 0x000001DEC1D85790, 184 bytes long. Data: < U > 80 55 D9 C1 DE 01 00 00 00 00 00 00 00 00 00 00 {14699} normal block at 0x000001DEC1D253A0, 176 bytes long. Data: < W X > 90 57 D8 C1 DE 01 00 00 90 58 D8 C1 DE 01 00 00 {14698} normal block at 0x000001DEC1D43FF0, 296 bytes long. Data: < P > A0 50 89 C3 DE 01 00 00 20 B5 DC C1 DE 01 00 00 {14697} normal block at 0x000001DEC389B5A0, 40 bytes long. Data: <@ ? > 40 F0 D0 C1 DE 01 00 00 F0 3F D4 C1 DE 01 00 00 {14690} normal block at 0x000001DEC3895B40, 16 bytes long. Data: < > 20 B5 DC C1 DE 01 00 00 01 00 00 00 00 00 00 00 {14689} normal block at 0x000001DEC389B610, 40 bytes long. Data: <P @[ > 50 E0 D0 C1 DE 01 00 00 40 5B 89 C3 DE 01 00 00 {14657} normal block at 0x000001DEC3895690, 9 bytes long. Data: <SEED-SRC > 53 45 45 44 2D 53 52 43 00 {14656} normal block at 0x000001DEC1D0E050, 200 bytes long. Data: <
> 60 1F D9 C1 DE 01 00 00 C4 00 00 00 00 00 00 00
{14612} normal block at 0x000001DEC38958C0, 9 bytes long.
Data: > 60 1F D9 C1 DE 01 00 00 C1 00 00 00 00 00 00 00 {13857} normal block at 0x000001DEC1D729C0, 84 bytes long. Data: < lobal default l> 00 6C 6F 62 61 6C 20 64 65 66 61 75 6C 74 20 6C {11535} normal block at 0x000001DEC1D248A0, 12 bytes long. Data: <AES-256-CTR > 41 45 53 2D 32 35 36 2D 43 54 52 00 {11533} normal block at 0x000001DEC1D83DF0, 240 bytes long. Data: < > 8A 03 00 00 01 00 00 00 20 00 00 00 10 00 00 00 {11218} normal block at 0x000001DEC1D430E0, 12 bytes long. Data: <AES-256-ECB > 41 45 53 2D 32 35 36 2D 45 43 42 00 {11216} normal block at 0x000001DEC1D95580, 240 bytes long. Data: < > AA 01 00 00 10 00 00 00 20 00 00 00 00 00 00 00 {11182} normal block at 0x000001DEC1D43090, 19 bytes long. Data: <BIO to Core filt> 42 49 4F 20 74 6F 20 43 6F 72 65 20 66 69 6C 74 {11181} normal block at 0x000001DEC1DADFB0, 112 bytes long. Data: < 0 > 19 04 00 00 00 00 00 00 90 30 D4 C1 DE 01 00 00 {11180} normal block at 0x000001DEC1DCB520, 24 bytes long. Data: <
pV > 60 1F D9 C1 DE 01 00 00 20 8B 70 56 F6 7F 00 00
{11179} normal block at 0x000001DEC1D42F50, 8 bytes long.
Data:
https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail Virus-free.www.avast.com https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
On Sat, Aug 10, 2024 at 3:22 PM Anarthal (Rubén Pérez) < @.***> wrote:
Okay, this didn't add any information. But that's because you defined _CRTDBG_MAP_ALLOC after including your own headers, so any allocations made in files included before the macro was defined are probably not tracked. Also, Boost.Test will do _CrtDumpMemoryLeaks for you. Doing it in your test case will report false positives, since there's memory that hasn't been released yet at that point.
My suggestion to move forward:
- Remove any _CrtXXXXX calls from your code.
- Define _CRTDBG_MAP_ALLOC first thing in your test. The easiest way to do it is to add a target_compile_definitions(you_executable PRIVATE _CRTDBG_MAP_ALLOC) command in your CMake.
Sorry that I didn't explain myself better in my previous post.
Regards, Ruben.
— Reply to this email directly, view it on GitHub https://github.com/boostorg/mysql/issues/327#issuecomment-2280705587, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABBCGY2EZTZRVCZK5XYFGKTZQXPEFAVCNFSM6AAAAABMB2MQHCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEOBQG4YDKNJYG4 . You are receiving this because you were mentioned.Message ID: @.***>
Oh :( let's try isolating this a little bit, and just testing the database component alone. For instance, let's check if this produces any leak report:
#include "Server/Auth/Auth.hpp"
#define BOOST_TEST_MODULE DatabaseProcessTest
#include <boost/test/included/unit_test.hpp>
BOOST_AUTO_TEST_CASE(DatabaseProcessTest)
{
// Feel free to change any of these values to what you see suit
std::string host = "127.0.0.1";
int port = 3306;
std::string user = "root";
std::string pass = "";
std::string database = "mydb";
int segment_number = -1;
// Create the component
boost::asio::io_context ctx;
DatabaseProcess proc;
// Use it
try {
proc.initialize(ctx, segment_number, host, port, user, pass, database);
} catch(const std::exception &e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
}
}
It works! There was no leak produced. And all ran smoothly. I think there would be an issue with something else that is causing the leaks?
On Sat, Aug 10, 2024 at 5:46 PM Anarthal (Rubén Pérez) < @.***> wrote:
Oh :( let's try isolating this a little bit, and just testing the database component alone. For instance, let's check if this produces any leak report:
include "Server/Auth/Auth.hpp"
define BOOST_TEST_MODULE DatabaseProcessTest
include <boost/test/included/unit_test.hpp>
BOOST_AUTO_TEST_CASE(DatabaseProcessTest) { // Feel free to change any of these values to what you see suit std::string host = "127.0.0.1"; int port = 3306; std::string user = "root"; std::string pass = ""; std::string database = "mydb"; int segment_number = -1;
// Create the component boost::asio::io_context ctx; DatabaseProcess proc; // Use it try { proc.initialize(ctx, segment_number, host, port, user, pass, database); } catch(const std::exception &e) { std::cerr << "Exception caught: " << e.what() << std::endl; }
}
— Reply to this email directly, view it on GitHub https://github.com/boostorg/mysql/issues/327#issuecomment-2281404188, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABBCGYYWDDKEUCO7L4AV6F3ZQYAA5AVCNFSM6AAAAABMB2MQHCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEOBRGQYDIMJYHA . You are receiving this because you were mentioned.Message ID: @.***>
Great! I'd say the leak is probably located in your codebase, and outside of DatabaseProcess
. Something is keeping a DatabaseProcess
alive and not deleting it correctly on termination.
A potential cause can be a cyclic reference using a std::shared_ptr
. These need to be broken manually.
The process I'd follow is to attempt to write smaller tests with individual components until one of them spits out the leak.
Also, I'd revise your usage of std::shared_ptr
, in general. For instance, if the horizon framework makes the guarantee that any MainframeComponent
's are kept alive until the application exits, you're safe to change get_connection
to:
boost::mysql::tcp_ssl_connection& get_connection() { return _connection; }
shared_ptr
can generate nasty stuff like the one you saw.
I'll close the issue now. If you have any more trouble or questions, don't hesitate to ask.
Regards, Ruben.
file.hpp
file.cpp
On application exit -