MySQL 8.4.0
Source Code Documentation
log_source_backtrace.cc File Reference

This file contains contains code to search for a recent stackdump in a file formatted in the "traditional error log" format. More...

#include <my_time.h>
#include <mysql_time.h>
#include <iostream>
#include "log_sink_buffer.h"
#include "log_sink_trad.h"
#include "my_dir.h"
#include "mysql/components/services/log_builtins.h"
#include "mysql/components/services/log_service.h"
#include "mysql/my_loglevel.h"
#include "mysqld_error.h"
#include "sql/log.h"
#include "sql/sql_list.h"

Functions

static log_service_error log_source_backtrace_add_events ()
 If a stack backtrace was found in the traditional error log, prepend its lines to buffered logging (so the backtrace may be flushed to performance_schema.error_log and all configured log-sinks later). More...
 
ulonglong log_iso8601_from_line (const char *line_start, const char *line_end)
 Parse an ISO-8601 compliant timestamp. More...
 
static log_service_error log_source_backtrace_parse_line (char *line_start, size_t line_length)
 Parse a single line in the traditional error-log. More...
 
static log_service_error log_error_read_backtrace_loop (const char *log_file, size_t size)
 Read tail end of the traditional error-log as a single chunk. More...
 
log_service_error log_error_read_backtrace (const char *log_name)
 Read stacktrace from previous failure. More...
 

Variables

static const size_t max_backtrace = 32 * 1024
 How far back in the trad error-log should we start looking? More...
 
static ulonglong iso8601_outside_stack = 0
 Latest ISO8601 timestamp found outside a stackdump. More...
 
static ulonglong iso8601_during_stack = 0
 ISO8601 timestamp in current stackdump. More...
 
static char * backtrace_beg = nullptr
 Pointer to first character of a textual stacktrace, or nullptr. More...
 
static char * backtrace_end = nullptr
 Pointer to last character of a textual stacktrace, or nullptr. More...
 

Detailed Description

This file contains contains code to search for a recent stackdump in a file formatted in the "traditional error log" format.

If one is found, it is prepended to the buffered log-events.

Function Documentation

◆ log_error_read_backtrace()

log_service_error log_error_read_backtrace ( const char *  log_name)

Read stacktrace from previous failure.

The signal-handler attempts to write a stacktrace to stderr. As stderr (and stdout) are redirected to the "traditional" error-log, that's where we'll have to look for stacktraces, even if we use a different log-sink otherwise (e.g. JSON, syslog, etc.).

Once we have determined whether such a log exists and is readable, we call

See also
log_error_read_backtrace_loop() to do the actual reading and parsing.

It should be noted that at the point this function is normally called, buffered error logging will not have been flushed yet.

Parameters
log_nameThe log file to read (log_error_dest).
Return values
LOG_SERVICE_SUCCESSSuccess (log read and parsed)
LOG_SERVICE_UNABLE_TO_READCould not read/access() file
LOG_SERVICE_INVALID_ARGUMENTInvalid log-file name
LOG_SERVICE_ARGUMENT_TOO_LONGFile-name too long
otherwiseReturn value from reader

◆ log_error_read_backtrace_loop()

static log_service_error log_error_read_backtrace_loop ( const char *  log_file,
size_t  size 
)
static

Read tail end of the traditional error-log as a single chunk.

Look for a recent stacktrace in that data.

Parameters
log_fileThe file's name
sizelength of the input file (in bytes)
Return values
LOG_SERVICE_SUCCESSsuccess
LOG_SERVICE_OPEN_FAILEDfailed to open file
LOG_SERVICE_SEEK_FAILEDseek failed
LOG_SERVICE_UNABLE_TO_READread failed or file empty
LOG_SERVICE_OUT_OF_MEMORYout of memory
LOG_SERVICE_PARSE_ERRORcould not find delimiter ('
')
LOG_SERVICE_MISC_ERRORparsing: sanity test failed

◆ log_iso8601_from_line()

ulonglong log_iso8601_from_line ( const char *  line_start,
const char *  line_end 
)

Parse an ISO-8601 compliant timestamp.

Parameters
line_startPointer to the first character of the line.
line_endPointer to the '
' ending the line.
Return values
Numberof micro-seconds since the epoch represented by the timestamp

◆ log_source_backtrace_add_events()

static log_service_error log_source_backtrace_add_events ( )
static

If a stack backtrace was found in the traditional error log, prepend its lines to buffered logging (so the backtrace may be flushed to performance_schema.error_log and all configured log-sinks later).

backtrace_beg must be set to the beginning of a char-buffer containing a textual stacktrace.

backtrace_end must point to the last valid character in the textual stacktrace.

The "textual representation" must consist of one or several lines terminated by '
'. These '
' will be replaced with '\0'.

Each line will become one log-event. The list of log-events, if any, will be prepended to the list of log-events buffered during start-up.

After this function returns, the caller is free to free() the buffer containing the log file fragment.

◆ log_source_backtrace_parse_line()

static log_service_error log_source_backtrace_parse_line ( char *  line_start,
size_t  line_length 
)
static

Parse a single line in the traditional error-log.

This function may be called to examine a buffer containing part of an error log line by line. If the header of a stack backtrace is recognized, certain variables are set up; if the end of a backtrace is recognized, those variables are cleared again. In other words, if the all the loaded log-lines have been examined and the variables are non-zero, the last chunk in the error log was a backtrace, and we have saved

  • iso8601_during_stack is non-zero and contains the time/date (micro-seconds since the epoch, UTC) of the backtrace.
  • backtrace_beg is non-null and points to the first character of the backtrace.
  • backtrace_end is non-null and points to the last character in the backtrace.

backtrace_beg and backtrace_end if set point to addresses in the temporary buffer that contains the error log fragment.

This function will attempt to determine whether the last item in the traditional error log is a backtrace and if so, identify the beginning and end of that backtrace in the buffer. It does not copy the information, add it to performance_schema.error_log, and so forth; this is something the caller can see to if desired.

Parameters
line_startPointer to the first character of the line.
line_lengthLength of the line in bytes.
Return values
LOG_SERVICE_MISC_ERRORlog was written to after server start

Variable Documentation

◆ backtrace_beg

char* backtrace_beg = nullptr
static

Pointer to first character of a textual stacktrace, or nullptr.

◆ backtrace_end

char* backtrace_end = nullptr
static

Pointer to last character of a textual stacktrace, or nullptr.

◆ iso8601_during_stack

ulonglong iso8601_during_stack = 0
static

ISO8601 timestamp in current stackdump.

◆ iso8601_outside_stack

ulonglong iso8601_outside_stack = 0
static

Latest ISO8601 timestamp found outside a stackdump.

◆ max_backtrace

const size_t max_backtrace = 32 * 1024
static

How far back in the trad error-log should we start looking?