2014-09-19 11 views
19

Dla celów śledzenia chciałbym wydrukować bieżącą nazwę funkcji, np. Makro __FUNCTION__ w gcc.golang: pobierz bieżący zakres nazwy funkcji

Tak, że gdy mam funkcji

func foo() { 
    trace() 
} 

zostanie ona automatycznie wydrukować Entering foo()... lub coś podobnego.

Odpowiedz

39

Pakiet runtime jest Twój przyjaciel tutaj:

func trace() { 
    pc := make([]uintptr, 10) // at least 1 entry needed 
    runtime.Callers(2, pc) 
    f := runtime.FuncForPC(pc[0]) 
    file, line := f.FileLine(pc[0]) 
    fmt.Printf("%s:%d %s\n", file, line, f.Name()) 
} 
+2

Och, Jezu, to Swank. Gdyby nie jakiś pomysłowy program wykonawczy był tak prosty. – twotwotwo

+1

Wow .. ja też. Będę musiał zmienić moje wyrażenie na ślad stosu do tego .. jego o wiele ładniejszy! +1 –

+0

Tylko FYI - dokumentacja stwierdza to, ale wydaje się to niedokładne. Nazywam to 3 metody głębokie i zgłasza wiersz 24 w pliku źródłowym, gdy jego wiersz 22. Następnie próbowałem wywołać jedną metodę głębokie i jest jeden wiersz wyłączony - nie wystarczająco dobry dla moich wymagań :(Dokumentacja stwierdza "wynik nie będzie dokładne, jeśli pc nie jest licznikiem programu w obrębie f' .. ale nie jestem pewien, jak powinienem to interpretować.nie wydaje się tak dokładne, jak wyodrębnianie pliku i numeru linii ze śledzenia stosu. –

6

Dla tych, patrząc na to pytanie w roku 2017 niektóre funkcje uruchomieniowe golang zostały dodane, które wydają się radzić sobie z niewłaściwy numer linii, która jest drukowana.

func trace2() { 
    pc := make([]uintptr, 15) 
    n := runtime.Callers(2, pc) 
    frames := runtime.CallersFrames(pc[:n]) 
    frame, _ := frames.Next() 
    fmt.Printf("%s,:%d %s\n", frame.File, frame.Line, frame.Function) 
} 

Playground: https://play.golang.org/p/z2kHQJoeUo