github.com/apache/beam/sdks/v2@v2.48.2/go/cmd/symtab/main.go (about) 1 // Licensed to the Apache Software Foundation (ASF) under one or more 2 // contributor license agreements. See the NOTICE file distributed with 3 // this work for additional information regarding copyright ownership. 4 // The ASF licenses this file to You under the Apache License, Version 2.0 5 // (the "License"); you may not use this file except in compliance with 6 // the License. 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 // Package verifies that functions sym2addr and addr2sym work correctly. 17 package main 18 19 import ( 20 "log" 21 "os" 22 "reflect" 23 24 "github.com/apache/beam/sdks/v2/go/pkg/beam/core/funcx" 25 "github.com/apache/beam/sdks/v2/go/pkg/beam/core/util/reflectx" 26 "github.com/apache/beam/sdks/v2/go/pkg/beam/core/util/symtab" 27 ) 28 29 const ( 30 name = "main.Increment" 31 arg = "calling increment function" 32 ) 33 34 var symbolTable *symtab.SymbolTable 35 var counter int64 36 var t reflect.Type 37 38 // Increment is the function that will be executed by its address. 39 // It increments a global var so we can check that it was indeed called. 40 func Increment(str string) { 41 log.Printf(str) 42 counter++ 43 } 44 45 func init() { 46 // Registers function in symbol table. 47 Increment("adding increment function to symbol table") 48 t = reflect.FuncOf([]reflect.Type{reflect.TypeOf(arg)}, []reflect.Type{}, false) 49 50 var err error 51 // First try the Linux location, since it's the most reliable. 52 symbolTable, err = symtab.New("/proc/self/exe") 53 if err == nil { 54 return 55 } 56 // For other OS's this works in most cases we need. If it doesn't, log 57 // an error and keep going. 58 symbolTable, err = symtab.New(os.Args[0]) 59 if err == nil { 60 return 61 } 62 panic("Can't initialize symbol resolver.") 63 } 64 65 func main() { 66 // Translates function symbol to address. 67 addr, err := symbolTable.Sym2Addr(name) 68 if err != nil { 69 log.Fatalf("error translating function name to address: %v", err) 70 return 71 } 72 73 // Restarts counter and calls increment function by its address. 74 counter = 0 75 ret, err := funcx.New(reflectx.MakeFunc(reflectx.LoadFunction(addr, t))) 76 if err != nil { 77 log.Fatalf("error creating function out of address") 78 return 79 } 80 ret.Fn.Call([]any{arg}) 81 82 // Checks that function was executed. 83 if counter != 1 { 84 log.Fatalf("error running function 'increment' through its address") 85 return 86 } 87 88 // Translates address back to function symbol. 89 symbol, err := symbolTable.Addr2Sym(addr) 90 if err != nil { 91 log.Fatalf("error translating address to function name") 92 return 93 } 94 95 // Checks that function name is correct. 96 if symbol != name { 97 log.Fatalf("error verifying translation from address to name") 98 return 99 } 100 log.Printf("success!") 101 }