diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-11-24 12:04:51 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-11-24 12:04:51 +0200 |
commit | 6b2b510839f18a8a235d60fd2da850795dfcfe3e (patch) | |
tree | dd636fd085809709a388644aa248b9f6f3da4204 /storage/perfschema | |
parent | 8d398710b35645be9eb85d0ef635870bea26748b (diff) | |
download | mariadb-git-6b2b510839f18a8a235d60fd2da850795dfcfe3e.tar.gz |
PFS_events_statements cleanup: Use offsetof
The macro my_offsetof() performs pointer arithmetics that may be
undefined behavior. As reported in MDEV-26272, it may cause
clang -fsanitize=undefined to generate invalid memory references.
struct PFS_events_statements: Convert to std::is_standard_layout
by encapsulating the standard-layout struct PFS_events instead of
deriving from it, so that the standard macro offsetof() can be used.
PFS_events_statements::copy(): Renamed from copy_events_statements().
A cast to void* is now needed in memcpy() to avoid GCC -Wclass-memaccess
"writing to an object ... leaves 64 bytes unchanged".
Diffstat (limited to 'storage/perfschema')
-rw-r--r-- | storage/perfschema/pfs.cc | 50 | ||||
-rw-r--r-- | storage/perfschema/pfs_events_statements.cc | 25 | ||||
-rw-r--r-- | storage/perfschema/pfs_events_statements.h | 5 | ||||
-rw-r--r-- | storage/perfschema/pfs_prepared_stmt.cc | 4 | ||||
-rw-r--r-- | storage/perfschema/table_events_statements.cc | 29 |
5 files changed, 58 insertions, 55 deletions
diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc index d7cac927d30..48641ab1c68 100644 --- a/storage/perfschema/pfs.cc +++ b/storage/perfschema/pfs.cc @@ -4841,8 +4841,8 @@ pfs_start_stage_v1(PSI_stage_key key, const char *src_file, int src_line) pfs->m_class= NULL; /* New waits will now be attached directly to the parent statement. */ - child_wait->m_event_id= parent_statement->m_event_id; - child_wait->m_event_type= parent_statement->m_event_type; + child_wait->m_event_id= parent_statement->m_event.m_event_id; + child_wait->m_event_type= parent_statement->m_event.m_event_type; /* See below for new stages, that may overwrite this. */ } @@ -4957,8 +4957,8 @@ void pfs_end_stage_v1() /* New waits will now be attached directly to the parent statement. */ PFS_events_waits *child_wait= & pfs_thread->m_events_waits_stack[0]; PFS_events_statements *parent_statement= & pfs_thread->m_statement_stack[0]; - child_wait->m_event_id= parent_statement->m_event_id; - child_wait->m_event_type= parent_statement->m_event_type; + child_wait->m_event_id= parent_statement->m_event.m_event_id; + child_wait->m_event_type= parent_statement->m_event.m_event_type; /* This stage is completed */ pfs->m_class= NULL; @@ -5009,13 +5009,13 @@ pfs_get_thread_statement_locker_v1(PSI_statement_locker_state *state, pfs_dirty_state dirty_state; pfs_thread->m_stmt_lock.allocated_to_dirty(& dirty_state); PFS_events_statements *pfs= & pfs_thread->m_statement_stack[pfs_thread->m_events_statements_count]; - pfs->m_thread_internal_id= pfs_thread->m_thread_internal_id; - pfs->m_event_id= event_id; - pfs->m_event_type= EVENT_TYPE_STATEMENT; - pfs->m_end_event_id= 0; - pfs->m_class= klass; - pfs->m_timer_start= 0; - pfs->m_timer_end= 0; + pfs->m_event.m_thread_internal_id= pfs_thread->m_thread_internal_id; + pfs->m_event.m_event_id= event_id; + pfs->m_event.m_event_type= EVENT_TYPE_STATEMENT; + pfs->m_event.m_end_event_id= 0; + pfs->m_event.m_class= klass; + pfs->m_event.m_timer_start= 0; + pfs->m_event.m_timer_end= 0; pfs->m_lock_time= 0; pfs->m_current_schema_name_length= 0; pfs->m_sqltext_length= 0; @@ -5065,9 +5065,9 @@ pfs_get_thread_statement_locker_v1(PSI_statement_locker_state *state, if (pfs_thread->m_events_statements_count > 0) { parent_statement= pfs - 1; - parent_event= parent_statement->m_event_id; - parent_type= parent_statement->m_event_type; - parent_level= parent_statement->m_nesting_event_level + 1; + parent_event= parent_statement->m_event.m_event_id; + parent_type= parent_statement->m_event.m_event_type; + parent_level= parent_statement->m_event.m_nesting_event_level + 1; } if (parent_transaction->m_state == TRANS_STATE_ACTIVE && @@ -5077,9 +5077,9 @@ pfs_get_thread_statement_locker_v1(PSI_statement_locker_state *state, parent_type= parent_transaction->m_event_type; } - pfs->m_nesting_event_id= parent_event; - pfs->m_nesting_event_type= parent_type; - pfs->m_nesting_event_level= parent_level; + pfs->m_event.m_nesting_event_id= parent_event; + pfs->m_event.m_nesting_event_type= parent_type; + pfs->m_event.m_nesting_event_level= parent_level; /* Set parent Stored Procedure information for this statement. */ if(sp_share) @@ -5197,7 +5197,7 @@ pfs_refine_statement_v1(PSI_statement_locker *locker, DBUG_ASSERT(pfs != NULL); /* mutate EVENTS_STATEMENTS_CURRENT.EVENT_NAME */ - pfs->m_class= klass; + pfs->m_event.m_class= klass; } state->m_class= klass; @@ -5233,9 +5233,9 @@ void pfs_start_statement_v1(PSI_statement_locker *locker, PFS_events_statements *pfs= reinterpret_cast<PFS_events_statements*> (state->m_statement); DBUG_ASSERT(pfs != NULL); - pfs->m_timer_start= timer_start; - pfs->m_source_file= src_file; - pfs->m_source_line= src_line; + pfs->m_event.m_timer_start= timer_start; + pfs->m_event.m_source_file= src_file; + pfs->m_event.m_source_line= src_line; DBUG_ASSERT(db_len <= sizeof(pfs->m_current_schema_name)); if (db_len > 0) @@ -5492,8 +5492,8 @@ void pfs_end_statement_v1(PSI_statement_locker *locker, void *stmt_da) break; } - pfs->m_timer_end= timer_end; - pfs->m_end_event_id= thread->m_event_id; + pfs->m_event.m_timer_end= timer_end; + pfs->m_event.m_end_event_id= thread->m_event_id; if (digest_storage != NULL) { @@ -5970,8 +5970,8 @@ pfs_get_thread_transaction_locker_v1(PSI_transaction_locker_state *state, { PFS_events_statements *pfs_statement= &pfs_thread->m_statement_stack[statements_count - 1]; - pfs->m_nesting_event_id= pfs_statement->m_event_id; - pfs->m_nesting_event_type= pfs_statement->m_event_type; + pfs->m_nesting_event_id= pfs_statement->m_event.m_event_id; + pfs->m_nesting_event_type= pfs_statement->m_event.m_event_type; } else { diff --git a/storage/perfschema/pfs_events_statements.cc b/storage/perfschema/pfs_events_statements.cc index e0f1b2bfb77..7c1ac8b1d5b 100644 --- a/storage/perfschema/pfs_events_statements.cc +++ b/storage/perfschema/pfs_events_statements.cc @@ -147,27 +147,26 @@ void cleanup_events_statements_history_long(void) h_long_stmts_text_array= NULL; } -static inline void copy_events_statements(PFS_events_statements *dest, - const PFS_events_statements *source) +inline void PFS_events_statements::copy(const PFS_events_statements &source) { /* Copy all attributes except SQL TEXT and DIGEST */ - memcpy(dest, source, my_offsetof(PFS_events_statements, m_sqltext)); + memcpy((void*) this, &source, offsetof(PFS_events_statements, m_sqltext)); /* Copy SQL TEXT */ - int sqltext_length= source->m_sqltext_length; + int sqltext_length= source.m_sqltext_length; if (sqltext_length > 0) { - memcpy(dest->m_sqltext, source->m_sqltext, sqltext_length); - dest->m_sqltext_length= sqltext_length; + memcpy(m_sqltext, source.m_sqltext, sqltext_length); + m_sqltext_length= sqltext_length; } else { - dest->m_sqltext_length= 0; + m_sqltext_length= 0; } /* Copy DIGEST */ - dest->m_digest_storage.copy(& source->m_digest_storage); + m_digest_storage.copy(&source.m_digest_storage); } /** @@ -192,7 +191,7 @@ void insert_events_statements_history(PFS_thread *thread, PFS_events_statements to make this thread (the writer) faster. This is ok, the readers of m_statements_history will filter this out. */ - copy_events_statements(&thread->m_statements_history[index], statement); + thread->m_statements_history[index].copy(*statement); index++; if (index >= events_statements_history_per_thread) @@ -221,7 +220,7 @@ void insert_events_statements_history_long(PFS_events_statements *statement) events_statements_history_long_full= true; /* See related comment in insert_events_statements_history. */ - copy_events_statements(&events_statements_history_long_array[index], statement); + events_statements_history_long_array[index].copy(*statement); } static void fct_reset_events_statements_current(PFS_thread *pfs_thread) @@ -230,7 +229,7 @@ static void fct_reset_events_statements_current(PFS_thread *pfs_thread) PFS_events_statements *pfs_stmt_last= pfs_stmt + statement_stack_max; for ( ; pfs_stmt < pfs_stmt_last; pfs_stmt++) - pfs_stmt->m_class= NULL; + pfs_stmt->m_event.m_class= nullptr; } /** Reset table EVENTS_STATEMENTS_CURRENT data. */ @@ -247,7 +246,7 @@ static void fct_reset_events_statements_history(PFS_thread *pfs_thread) pfs_thread->m_statements_history_index= 0; pfs_thread->m_statements_history_full= false; for ( ; pfs < pfs_last; pfs++) - pfs->m_class= NULL; + pfs->m_event.m_class= nullptr; } /** Reset table EVENTS_STATEMENTS_HISTORY data. */ @@ -265,7 +264,7 @@ void reset_events_statements_history_long(void) PFS_events_statements *pfs= events_statements_history_long_array; PFS_events_statements *pfs_last= pfs + events_statements_history_long_size; for ( ; pfs < pfs_last; pfs++) - pfs->m_class= NULL; + pfs->m_event.m_class= nullptr; } static void fct_reset_events_statements_by_thread(PFS_thread *thread) diff --git a/storage/perfschema/pfs_events_statements.h b/storage/perfschema/pfs_events_statements.h index 8b24a9e75c8..a21e1c4980c 100644 --- a/storage/perfschema/pfs_events_statements.h +++ b/storage/perfschema/pfs_events_statements.h @@ -38,8 +38,9 @@ struct PFS_user; struct PFS_host; /** A statement record. */ -struct PFS_events_statements : public PFS_events +struct PFS_events_statements { + PFS_events m_event; enum_object_type m_sp_type; char m_schema_name[NAME_LEN]; uint m_schema_name_length; @@ -117,6 +118,8 @@ struct PFS_events_statements : public PFS_events and always point to pre allocated memory. */ sql_digest_storage m_digest_storage; + + inline void copy(const PFS_events_statements &source); }; void insert_events_statements_history(PFS_thread *thread, PFS_events_statements *statement); diff --git a/storage/perfschema/pfs_prepared_stmt.cc b/storage/perfschema/pfs_prepared_stmt.cc index dcb7991633a..5885f31857a 100644 --- a/storage/perfschema/pfs_prepared_stmt.cc +++ b/storage/perfschema/pfs_prepared_stmt.cc @@ -126,9 +126,9 @@ create_prepared_stmt(void *identity, if (pfs_stmt) { if (pfs_program) - pfs->m_owner_event_id= pfs_stmt->m_nesting_event_id; + pfs->m_owner_event_id= pfs_stmt->m_event.m_nesting_event_id; else - pfs->m_owner_event_id= pfs_stmt->m_event_id; + pfs->m_owner_event_id= pfs_stmt->m_event.m_event_id; } /* Insert this record. */ diff --git a/storage/perfschema/table_events_statements.cc b/storage/perfschema/table_events_statements.cc index 9404bd87fcb..1fb02eddc48 100644 --- a/storage/perfschema/table_events_statements.cc +++ b/storage/perfschema/table_events_statements.cc @@ -228,17 +228,18 @@ void table_events_statements_common::make_row_part_1(PFS_events_statements *stat m_row_exists= false; - PFS_statement_class *unsafe= (PFS_statement_class*) statement->m_class; + PFS_statement_class *unsafe= (PFS_statement_class*) + statement->m_event.m_class; PFS_statement_class *klass= sanitize_statement_class(unsafe); if (unlikely(klass == NULL)) return; - m_row.m_thread_internal_id= statement->m_thread_internal_id; - m_row.m_event_id= statement->m_event_id; - m_row.m_end_event_id= statement->m_end_event_id; - m_row.m_nesting_event_id= statement->m_nesting_event_id; - m_row.m_nesting_event_type= statement->m_nesting_event_type; - m_row.m_nesting_event_level= statement->m_nesting_event_level; + m_row.m_thread_internal_id= statement->m_event.m_thread_internal_id; + m_row.m_event_id= statement->m_event.m_event_id; + m_row.m_end_event_id= statement->m_event.m_end_event_id; + m_row.m_nesting_event_id= statement->m_event.m_nesting_event_id; + m_row.m_nesting_event_type= statement->m_event.m_nesting_event_type; + m_row.m_nesting_event_level= statement->m_event.m_nesting_event_level; if (m_row.m_end_event_id == 0) { @@ -246,10 +247,10 @@ void table_events_statements_common::make_row_part_1(PFS_events_statements *stat } else { - timer_end= statement->m_timer_end; + timer_end= statement->m_event.m_timer_end; } - m_normalizer->to_pico(statement->m_timer_start, timer_end, + m_normalizer->to_pico(statement->m_event.m_timer_start, timer_end, & m_row.m_timer_start, & m_row.m_timer_end, & m_row.m_timer_wait); m_row.m_lock_time= statement->m_lock_time * MICROSEC_TO_PICOSEC; @@ -662,7 +663,7 @@ int table_events_statements_current::rnd_pos(const void *pos) statement= &pfs_thread->m_statement_stack[m_pos.m_index_2]; - if (statement->m_class != NULL) + if (statement->m_event.m_class) { make_row(pfs_thread, statement); return 0; @@ -762,7 +763,7 @@ int table_events_statements_history::rnd_next(void) statement= &pfs_thread->m_statements_history[m_pos.m_index_2]; - if (statement->m_class != NULL) + if (statement->m_event.m_class) { make_row(pfs_thread, statement); /* Next iteration, look for the next history in this thread */ @@ -793,7 +794,7 @@ int table_events_statements_history::rnd_pos(const void *pos) return HA_ERR_RECORD_DELETED; statement= &pfs_thread->m_statements_history[m_pos.m_index_2]; - if (statement->m_class != NULL) + if (statement->m_event.m_class) { make_row(pfs_thread, statement); return 0; @@ -876,7 +877,7 @@ int table_events_statements_history_long::rnd_next(void) { statement= &events_statements_history_long_array[m_pos.m_index]; - if (statement->m_class != NULL) + if (statement->m_event.m_class) { make_row(statement); /* Next iteration, look for the next entry */ @@ -908,7 +909,7 @@ int table_events_statements_history_long::rnd_pos(const void *pos) statement= &events_statements_history_long_array[m_pos.m_index]; - if (statement->m_class == NULL) + if (!statement->m_event.m_class) return HA_ERR_RECORD_DELETED; make_row(statement); |