github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/gadgets/trace/signal/tracer/gadget.go (about)

     1  // Copyright 2022-2023 The Inspektor Gadget authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package tracer
    16  
    17  import (
    18  	"errors"
    19  	"strconv"
    20  	"strings"
    21  
    22  	gadgetregistry "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-registry"
    23  	"github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets"
    24  	"github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/signal/types"
    25  	"github.com/inspektor-gadget/inspektor-gadget/pkg/params"
    26  	"github.com/inspektor-gadget/inspektor-gadget/pkg/parser"
    27  )
    28  
    29  type GadgetDesc struct{}
    30  
    31  func (g *GadgetDesc) Name() string {
    32  	return "signal"
    33  }
    34  
    35  func (g *GadgetDesc) Category() string {
    36  	return gadgets.CategoryTrace
    37  }
    38  
    39  func (g *GadgetDesc) Type() gadgets.GadgetType {
    40  	return gadgets.TypeTrace
    41  }
    42  
    43  func (g *GadgetDesc) Description() string {
    44  	return "Trace signals received by processes"
    45  }
    46  
    47  const (
    48  	ParamPID          = "pid"
    49  	ParamTargetSignal = "signal"
    50  	ParamFailedOnly   = "failed-only"
    51  	ParamKillOnly     = "kill-only"
    52  )
    53  
    54  func (g *GadgetDesc) ParamDescs() params.ParamDescs {
    55  	return params.ParamDescs{
    56  		{
    57  			Key:          ParamPID,
    58  			DefaultValue: "0",
    59  			Description:  "Show only signal sent by this particular PID",
    60  			TypeHint:     params.TypeInt32,
    61  		},
    62  		{
    63  			Key:         ParamTargetSignal,
    64  			Description: `Trace only this signal (it can be an int like 9 or string beginning with "SIG" like "SIGKILL")`,
    65  			Validator:   validateSignal,
    66  		},
    67  		{
    68  			Key:          ParamFailedOnly,
    69  			Alias:        "f",
    70  			DefaultValue: "false",
    71  			Description:  "Show only events where the syscall sending a signal failed",
    72  			TypeHint:     params.TypeBool,
    73  		},
    74  		{
    75  			Key:          ParamKillOnly,
    76  			Alias:        "k",
    77  			DefaultValue: "false",
    78  			Description:  "Show only events issued by kill syscall",
    79  			TypeHint:     params.TypeBool,
    80  		},
    81  	}
    82  }
    83  
    84  func (g *GadgetDesc) Parser() parser.Parser {
    85  	return parser.NewParser[types.Event](types.GetColumns())
    86  }
    87  
    88  func (g *GadgetDesc) EventPrototype() any {
    89  	return &types.Event{}
    90  }
    91  
    92  func init() {
    93  	gadgetregistry.Register(&GadgetDesc{})
    94  }
    95  
    96  // validateSignal checks whether the signal argument is empty, contains a number, or starts with "SIG".
    97  // We cannot perform the same check signalStringToInt does, because that is not cross-platform compatible.
    98  func validateSignal(signal string) error {
    99  	if signal == "" {
   100  		return nil
   101  	}
   102  	if strings.HasPrefix(signal, "SIG") {
   103  		return nil
   104  	}
   105  	if _, err := strconv.Atoi(signal); err == nil {
   106  		return nil
   107  	}
   108  	return errors.New("expected a signal number or a signal name starting with 'SIG'")
   109  }