MDEV-34534 main.plugin_load(daemon_example) - AddressSanitizer: Joining already joined thread, aborting

Joining with a thread that has previously been joined results in undefined behavior.

This example plugin performs the same join to the same thread a few
lines later. ASAN keeps track of this and fails.

Make the behaviour defined by joining only once.

Thanks Vladislav Vaintroub for looking up the behaviour.

While here;
* init/deinit function argument was actually used.
* correct code comments
* attribute define not needed

Thanks Marko Mäkelä for review and suggesting other
fixes.
This commit is contained in:
Daniel Black 2024-11-18 21:02:19 +11:00
parent b65504b8db
commit 1d6502b4f4

View file

@ -26,14 +26,6 @@
#include "m_string.h" // strlen
#include "sql_plugin.h" // st_plugin_int
/*
Disable __attribute__() on non-gcc compilers.
*/
#if !defined(__attribute__) && !defined(__GNUC__)
#define __attribute__(A)
#endif
#define HEART_STRING_BUFFER 100
struct mysql_heartbeat_context
@ -77,14 +69,14 @@ pthread_handler_t mysql_heartbeat(void *p)
daemon_example_plugin_init()
DESCRIPTION
Starts up heartbeatbeat thread
Starts up heartbeat thread (mysql_heartbeat)
RETURN VALUE
0 success
1 failure (cannot happen)
*/
static int daemon_example_plugin_init(void *p __attribute__ ((unused)))
static int daemon_example_plugin_init(void *p)
{
DBUG_ENTER("daemon_example_plugin_init");
@ -150,7 +142,7 @@ static int daemon_example_plugin_init(void *p __attribute__ ((unused)))
*/
static int daemon_example_plugin_deinit(void *p __attribute__ ((unused)))
static int daemon_example_plugin_deinit(void *p)
{
DBUG_ENTER("daemon_example_plugin_deinit");
char buffer[HEART_STRING_BUFFER];
@ -162,6 +154,10 @@ static int daemon_example_plugin_deinit(void *p __attribute__ ((unused)))
pthread_cancel(con->heartbeat_thread);
pthread_join(con->heartbeat_thread, NULL);
/*
As thread is joined, we can close the file it writes to and
free the memory it uses.
*/
localtime_r(&result, &tm_tmp);
my_snprintf(buffer, sizeof(buffer),
@ -174,12 +170,6 @@ static int daemon_example_plugin_deinit(void *p __attribute__ ((unused)))
tm_tmp.tm_sec);
my_write(con->heartbeat_file, (uchar*) buffer, strlen(buffer), MYF(0));
/*
Need to wait for the hearbeat thread to terminate before closing
the file it writes to and freeing the memory it uses.
*/
pthread_join(con->heartbeat_thread, NULL);
my_close(con->heartbeat_file, MYF(0));
my_free(con);