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 }