Skip to content

Commit

Permalink
Add Ruby seg fault exception tracing
Browse files Browse the repository at this point in the history
Ruby seg faults contain a lot of useful information. When the lines
are split across log entries, it makes debugging quite difficult.
  • Loading branch information
stanhu committed Feb 8, 2022
1 parent 17c846b commit bb69399
Show file tree
Hide file tree
Showing 2 changed files with 318 additions and 2 deletions.
54 changes: 52 additions & 2 deletions lib/fluent/plugin/exception_detector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module Fluent
Struct.new('Rule', :from_states, :pattern, :to_state)

# Configuration of the state machine that detects exceptions.
module ExceptionDetectorConfig
module ExceptionDetectorConfig # rubocop:disable Metrics/ModuleLength
# Rule for a state transition: if pattern matches go to the given state.
class RuleTarget
attr_accessor :pattern, :to_state
Expand Down Expand Up @@ -106,13 +106,59 @@ def self.supported
rule(:go_frame_2, /^\s/, :go_frame_1)
].freeze

RUBY_RULES = [
RUBY_ERROR_RULES = [
rule(:start_state, /Error \(.*\):$/, :ruby_before_rails_trace),
rule(:ruby_before_rails_trace, /^ $/, :ruby),
rule(:ruby_before_rails_trace, /^[\t ]+.*?\.rb:\d+:in `/, :ruby),
rule(:ruby, /^[\t ]+.*?\.rb:\d+:in `/, :ruby)
].freeze

RUBY_SEGFAULT_RULES = [
rule(:start_state,
/:\d+:\s\[BUG\] Segmentation fault/, :ruby_description),
rule(:ruby_description, /^ruby\n*/, :ruby_description_end),
rule(:ruby_description_end, /\n$/, :ruby_control_frame_begin),
rule(:ruby_control_frame_begin,
/^-- Control frame information --/, :ruby_control_frames),
rule(:ruby_control_frames, /^c:/, :ruby_control_frames),
rule(:ruby_control_frames, /^\n$/, :ruby_level_backtrace_frame_start),
rule(:ruby_level_backtrace_frame_start,
/-- Ruby level backtrace information --/,
:ruby_level_backtrace_frames),
rule(:ruby_level_backtrace_frames, /:\d+:in /,
:ruby_level_backtrace_frames),
rule(:ruby_level_backtrace_frames, /^\n$/, :ruby_level_backtrace_end),
rule(:ruby_level_backtrace_end,
/^-- Machine register context --/, :ruby_machine_registers),
rule(:ruby_machine_registers, /: /, :ruby_machine_registers),
rule(:ruby_machine_registers, /^\n$/, :ruby_machine_registers_end),
rule(:ruby_machine_registers_end,
/^-- C level backtrace information --/,
:ruby_c_level_backtrace_frames),
rule(:ruby_c_level_backtrace_frames, /\[.*\]/,
:ruby_c_level_backtrace_frames),
rule(:ruby_c_level_backtrace_frames, /^\n$/,
:ruby_c_level_backtrace_end),
rule(:ruby_c_level_backtrace_end,
/^-- Other runtime information/, :ruby_other_runtime_info),
rule(:ruby_other_runtime_info, /^\n$/, :ruby_other_runtime_info),
rule(:ruby_other_runtime_info, /^* Loaded script:/, :ruby_loaded_script),
rule(:ruby_loaded_script, /^\n$/, :ruby_loaded_features),
rule(:ruby_loaded_features, /^* Loaded features:/, :ruby_loaded_features),
rule(:ruby_loaded_features, /^\n$/, :ruby_loaded_features_frames),
rule(:ruby_loaded_features_frames,
/\d/, :ruby_loaded_features_frames),
rule(:ruby_loaded_features_frames,
/^\n$/, :ruby_process_memory_map),
rule(:ruby_process_memory_map,
/^* Process memory map:/, :ruby_process_memory_map),
rule(:ruby_process_memory_map,
/^\n$/, :ruby_process_memory_map_frames),
rule(:ruby_process_memory_map_frames,
/\-/, :ruby_process_memory_map_frames),
rule(:ruby_process_memory_map_frames, /^\n$/, :start_state)
].freeze

DART_RULES = [
rule(:start_state, /^Unhandled exception:$/, :dart_exc),
rule(:dart_exc, /^Instance of/, :dart_stack),
Expand Down Expand Up @@ -149,6 +195,10 @@ def self.supported
rule(:dart_stack, /^<asynchronous suspension>$/, :dart_stack)
].freeze

RUBY_RULES = (
RUBY_ERROR_RULES + RUBY_SEGFAULT_RULES
).freeze

ALL_RULES = (
JAVA_RULES + PYTHON_RULES + PHP_RULES + GO_RULES + RUBY_RULES + DART_RULES
).freeze
Expand Down
Loading

0 comments on commit bb69399

Please sign in to comment.