github.com/luchsh/agentlib.go@v0.0.0-20221115155834-ffd0caec4d72/jgo/test_lib.go (about)

     1  //
     2  // Copyright 2020 chuanshenglu@gmail.com
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  // http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  // +build ignore
    18  
    19  package main
    20  
    21  import (
    22  	"fmt"
    23  	"io"
    24  	"log"
    25  	"net/http"
    26  	"sync/atomic"
    27  	"time"
    28  )
    29  
    30  // This file contains the code that user has to write
    31  var classesLoaded int64
    32  
    33  // AgentGoOnLoad is the mandatory global hook provided by user code
    34  func AgentGoOnLoad(lib *AgentLib) {
    35  	fmt.Println("GO: AgentGoOnload")
    36  	fmt.Println("GO: Agent command line options:", lib.options)
    37  	lib.GetCallbacks().SetCallback(JVMTI_EVENT_VM_INIT, func(jvmti JvmtiEnv, args ...JvmtiArg) {
    38  		p := jvmti.Allocate(int64(4096))
    39  		defer jvmti.Deallocate(p)
    40  		fmt.Printf("GO: OnJvmtiVmInit(): triggered on Go level\np=%v\n", p)
    41  
    42  		ch := make(chan bool)
    43  		TestMain(lib.jvmti, ch)
    44  		//<-ch
    45  	})
    46  	lib.GetCallbacks().SetCallback(JVMTI_EVENT_CLASS_LOAD, func(jvmti JvmtiEnv, args ...JvmtiArg) {
    47  		name := jvmti.GetClassSignature(uintptr(args[2]))
    48  		fmt.Printf("GO: ClassLoad [%d] event: %s\n", classesLoaded, name)
    49  		atomic.AddInt64(&classesLoaded, int64(1))
    50  	})
    51  	lib.GetCallbacks().SetCallback(JVMTI_EVENT_CLASS_PREPARE, func(jvmti JvmtiEnv, args ...JvmtiArg) {
    52  		name := jvmti.GetClassSignature(uintptr(args[2]))
    53  		fmt.Println("GO: ClassPrepare event: ", name)
    54  	})
    55  	lib.GetCallbacks().SetCallback(JVMTI_EVENT_AGENT_UNLOAD, func(jvmti JvmtiEnv, args ...JvmtiArg) {
    56  		fmt.Println("GO: AgentUnloaded")
    57  	})
    58  	lib.GetCallbacks().SetCallback(JVMTI_EVENT_METHOD_ENTRY, func(jvmti JvmtiEnv, args ...JvmtiArg) {
    59  		fmt.Println("GO: method entry")
    60  	})
    61  	lib.GetCallbacks().SetCallback(JVMTI_EVENT_METHOD_EXIT, func(jvmti JvmtiEnv, args ...JvmtiArg) {
    62  		fmt.Println("GO: method exit")
    63  	})
    64  
    65  	go func() {
    66  		http.HandleFunc("/classesLoaded", func(w http.ResponseWriter, _ *http.Request) {
    67  			io.WriteString(w, fmt.Sprintf("Total classes loaded: %d\n", classesLoaded))
    68  		})
    69  		println("Server loaded...")
    70  		log.Fatal(http.ListenAndServe("0.0.0.0:8080", nil))
    71  	}()
    72  }
    73  
    74  func AgentGoOnUnload() {
    75  	fmt.Println("GO: AgentGoOnUnload")
    76  }
    77  
    78  func testThreads(jvmti JvmtiEnv) {
    79  	allThreads := jvmti.GetAllThreads()
    80  	if len(allThreads) <= 0 {
    81  		panic("Failed to get all threads")
    82  	}
    83  	for _,t := range allThreads {
    84  		info := jvmti.GetThreadInfo(t)
    85  		fmt.Printf("Thread %v %v\n", t, info)
    86  	}
    87  }
    88  
    89  func TestMain(jvmti JvmtiEnv, ch chan bool) {
    90  	time.Sleep(5 * time.Second)
    91  	testThreads(jvmti)
    92  	//ch <- true
    93  }