github.com/matrixorigin/matrixone@v0.7.0/pkg/common/moprobe/probe.go (about)

     1  // Copyright 2021 - 2023 Matrix Origin
     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  //
    16  // Poorman's usdt probe.
    17  // Using bpftrace to trace go user space code is hard.  There are a few problems with go runtime
    18  //  1. you simply cannot use uretprobe.  Go runtime may move stack around and return probe simply
    19  //     does not work.
    20  //  2. the argument to uprobe is rather hard to get.  Golang ABI changed so most of the stuff you
    21  //     find on the web is obsolete.
    22  //  3. there are ways of creating usdt with rather sophisticated bpf hacks, but I don't think it
    23  //     can be understood by meer mortal.
    24  //  4. thread id is not meaningful in go.  goroutine id is also fishy and rather hard to get.  Thread
    25  //     id is extremely important/useful for tracing.
    26  //
    27  // Anyway, I didn't find a "satisfying" solution, so let's roll out our own.   It is extremely simple.
    28  // When you need a static tracepoint, simply create a function here in this file.  The function should take
    29  // *AT MOST* 9 arguments, *ALL* of them *int64*.  If you want to pass in a string, then use 2 params, a pointer
    30  // that is converted to int64, and a length (you don't need this one if length is not needed).  The arguments
    31  // are available in bpftrace in registers.  DO NOT pass in complex data structures as arg.  Go will put those
    32  // on stack and it is simply impossible for bpftrace to decode.
    33  //
    34  // We suggest you always use first argument as a tag -- this is roughly the tid of C program.  You use this
    35  // to track function call and return so that you won't mix call/return from different go routines.  A pointer
    36  // of context, or go data structure converted to int64 usually works well.
    37  //
    38  // Not the noinline pragma. We will use bpftrace uprobe -- it can not be probed if the function is inlined.
    39  //
    40  // The following is here for reference.   See latest golang ABI for any changes.
    41  //
    42  // For AMD64, the register for args are
    43  // 	ax, bx, cx, di, si, r8, r9, r10, r11
    44  // Note that bpftrace does not use eax, rax, etc.   It is simply ax.   You can print out with %ld or %lx to get
    45  // the full 8 bytes.
    46  //
    47  // For arm64, the registers are r0 - r15.
    48  //
    49  
    50  package moprobe
    51  
    52  //go:noinline
    53  func DisttaePartitionInsert(tag, v1 int64) {
    54  }
    55  
    56  //go:noinline
    57  func DisttaePartitionInsertRet(tag, v1 int64) {
    58  }