मेरे पास जावा बैकग्राउंड है, और मुझे जावा थ्रेड डंप का निरीक्षण करने के लिए सिग्नल QUIT का उपयोग करना पसंद है।
गोलंग को सभी गोरोइन्ट्स स्टैक ट्रेस को कैसे जाने दें?
मेरे पास जावा बैकग्राउंड है, और मुझे जावा थ्रेड डंप का निरीक्षण करने के लिए सिग्नल QUIT का उपयोग करना पसंद है।
गोलंग को सभी गोरोइन्ट्स स्टैक ट्रेस को कैसे जाने दें?
जवाबों:
के लिए स्टैक ट्रेस मुद्रित करने के लिए वर्तमान goroutine, का उपयोग PrintStack()सेruntime/debug ।
PrintStack मानक त्रुटि के लिए प्रिंट करता है स्टैक द्वारा लौटाए गए स्टैक ट्रेस।
उदाहरण के लिए:
import(
"runtime/debug"
)
...
debug.PrintStack()
सभी goroutines के उपयोग Lookupऔर WriteToसे स्टैक ट्रेस प्रिंट करने के लिए runtime/pprof।
func Lookup(name string) *Profile
// Lookup returns the profile with the given name,
// or nil if no such profile exists.
func (p *Profile) WriteTo(w io.Writer, debug int) error
// WriteTo writes a pprof-formatted snapshot of the profile to w.
// If a write to w returns an error, WriteTo returns that error.
// Otherwise, WriteTo returns nil.
प्रत्येक प्रोफ़ाइल का एक अद्वितीय नाम है। कुछ प्रोफाइल पूर्वनिर्धारित हैं:
goroutine - सभी वर्तमान goroutines
ढेर के
ढेर के निशान - सभी ढेर आवंटन का एक नमूना थ्रेडक्रिएट - स्टैक के निशान जिसके कारण नए OS थ्रेड
ब्लॉक का निर्माण हुआ - स्टैक के निशान जिसके कारण सिंक्रोनस प्राइमेटीज पर अवरुद्ध हो गया।
उदाहरण के लिए:
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
Stack। "स्टैक गोरोइन का एक स्वरूपित स्टैक ट्रेस देता है जो इसे कॉल करता है। प्रत्येक दिनचर्या के लिए, इसमें स्रोत लाइन की जानकारी और पीसी मूल्य शामिल है, फिर गो फ़ंक्शन, कॉलिंग फ़ंक्शन या विधि और लाइन वाले पाठ के लिए खोज करने का प्रयास करता है। मंगलाचरण।"
runtime/pprofइंटरमेरनेट के उत्तर में उल्लिखित पैकेज के लिए एक HTTP फ्रंटएंड है । के लिए HTTP हैंडलर रजिस्टर करने के लिए नेट / http / pprof पैकेज आयात करें /debug/pprof:
import _ "net/http/pprof"
import _ "net/http"
यदि आपके पास पहले से कोई नहीं है, तो एक HTTP श्रोता शुरू करें:
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
फिर http://localhost:6060/debug/pprofएक मेनू के http://localhost:6060/debug/pprof/goroutine?debug=2लिए या पूर्ण गोरोइन स्टैक डंप के लिए एक ब्राउज़र इंगित करें ।
अन्य मजेदार चीजें हैं जो आप अपने रनिंग कोड के बारे में भी सीख सकते हैं। उदाहरण और अधिक जानकारी के लिए ब्लॉग पोस्ट देखें: http://blog.golang.org/profiling-go-programs
SIGQUIT पर स्टैक-डंप के जावा व्यवहार की नक़ल करना
go func() {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGQUIT)
buf := make([]byte, 1<<20)
for {
<-sigs
stacklen := runtime.Stack(buf, true)
log.Printf("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end\n", buf[:stacklen])
}
}()
जावा के समान, SIGQUIT का उपयोग एक गो कार्यक्रम और इसके गोरआउट्स के स्टैक ट्रेस को प्रिंट करने के लिए किया जा सकता है।
हालाँकि, एक प्रमुख अंतर यह है कि डिफ़ॉल्ट रूप से जावा प्रोग्राम को SIGQUIT भेजना उन्हें समाप्त नहीं करता है, जबकि Go प्रोग्राम बाहर निकलते हैं।
इस दृष्टिकोण को मौजूदा कार्यक्रमों के सभी गोरआउट्स के स्टैक ट्रेस को मुद्रित करने के लिए कोई कोड परिवर्तन की आवश्यकता नहीं है।
पर्यावरण चर GOTRACEBACK ( रनटाइम पैकेज के प्रलेखन देखें) ) उत्पन्न उत्पादन की मात्रा को नियंत्रित करता है। उदाहरण के लिए, सभी गोरआउट्स को शामिल करने के लिए, GOTRACEBACK = सभी सेट करें।
स्टैक ट्रेस की छपाई को एक अनपेक्षित रनटाइम कंडीशन (अनहेल्ड सिग्नल) द्वारा ट्रिगर किया जाता है, मूल रूप से इस कमिट में प्रलेखित है , जो कम से कम गो 1.1 के बाद से उपलब्ध है।
वैकल्पिक रूप से, यदि स्रोत कोड को संशोधित करना एक विकल्प है, तो अन्य उत्तर देखें।
ध्यान दें कि लिनक्स टर्मिनल में, SIGQUIT को आसानी से कुंजी संयोजन Ctrl+ के साथ भेजा जा सकता है \।
आप सभी goroutines के स्टैक ट्रेस पाने के लिए runtime.Stack का उपयोग कर सकते हैं :
buf := make([]byte, 1<<16)
runtime.Stack(buf, true)
fmt.Printf("%s", buf)
प्रलेखन से:
func Stack(buf []byte, all bool) int
स्टैक, कॉलिंग गोरोइन के एक स्टैक को buf में प्रारूपित करता है और buf को लिखे गए बाइट्स की संख्या लौटाता है। यदि सब सही है, तो स्टैक प्रारूप वर्तमान गोरोइन के लिए ट्रेस के बाद अन्य सभी गोरोइनों के निशान को बफ़ में जोड़ देता है।
string(buf)यहां करने की आवश्यकता नहीं है, fmt.Printf("%s", buf)और fmt.Printf("%s", string(buf))ठीक उसी काम को करें ( fmtपैकेज के लिए डॉक्स देखें ); यहाँ केवल अंतर यह है कि stringसंस्करण bufअनावश्यक रूप से बाइट्स की नकल करेगा
प्रेस Ctrl + \
(यदि आप इसे एक टर्मिनल में चलाते हैं और सिर्फ अपने प्रोग्राम को मारना चाहते हैं और गो रूट आदि को डंप करते हैं)
मुझे यह प्रश्न प्रमुख अनुक्रम की तलाश में मिला। बस एक त्वरित और आसान तरीका बताना चाहता था कि क्या मेरा कार्यक्रम लीक हो रहा है :)
पर * NIX सिस्टम (OSX सहित) एक संकेत गर्भपात भेजें SIGABRT:
pkill -SIGABRT program_name
runtime.Stack()आपके स्टैक ट्रेस के बाद खाली लाइनों के एक गुच्छा को प्रिंट करने से बचने के लिए लौटे लंबाई का उपयोग करना आवश्यक है । निम्न पुनर्प्राप्ति फ़ंक्शन एक अच्छी तरह से स्वरूपित ट्रेस प्रिंट करता है:
if r := recover(); r != nil {
log.Printf("Internal error: %v", r))
buf := make([]byte, 1<<16)
stackSize := runtime.Stack(buf, true)
log.Printf("%s\n", string(buf[0:stackSize]))
}
डिफ़ॉल्ट रूप से, सभी गोरआउट्स के स्टैक के निशान को डंप करने के लिए ^\( CTRL + \ ) दबाएँ ।
अन्यथा, अधिक दानेदार नियंत्रण के लिए, आप उपयोग कर सकते हैं panic। गो 1.6+ का सरल तरीका :
go func() {
s := make(chan os.Signal, 1)
signal.Notify(s, syscall.SIGQUIT)
<-s
panic("give me the stack")
}()
फिर, अपना प्रोग्राम ऐसे चलाएं:
# Press ^\ to dump the stack traces of all the user-created goroutines
$ GOTRACEBACK=all go run main.go
अगर आप भी गो रनटाइम गोरोइन प्रिंट करना चाहते हैं:
$ GOTRACEBACK=system go run main.go
यहां सभी GOTRACEBACK विकल्प दिए गए हैं:
GOTRACEBACK=none गोरोइन स्टैक के निशान को पूरी तरह से छोड़ देता है।GOTRACEBACK=single (डिफ़ॉल्ट) ऊपर वर्णित अनुसार व्यवहार करता है।GOTRACEBACK=all सभी उपयोगकर्ता-निर्मित गोरआउट के लिए स्टैक के निशान जोड़ता है।GOTRACEBACK=system `` 'की तरह है, लेकिन रन-टाइम फ़ंक्शंस के लिए स्टैक फ़्रेम जोड़ता है और रन-टाइम द्वारा आंतरिक रूप से बनाए गए गोरआउट्स दिखाता है।GOTRACEBACK=crash`` सिस्टम 'की तरह है, लेकिन बाहर निकलने के बजाय एक ऑपरेटिंग सिस्टम-विशिष्ट तरीके से क्रैश होता है। उदाहरण के लिए, यूनिक्स प्रणालियों पर, क्रैश SIGABRTएक कोर डंप को ट्रिगर करने के लिए उठता है।GOTRACEBACK वैरिएबल उत्पादन की मात्रा को नियंत्रित करता है जब एक अपरिवर्तित आतंक या अप्रत्याशित रनटाइम स्थिति के कारण एक गो कार्यक्रम विफल हो जाता है।
डिफ़ॉल्ट रूप से, एक विफलता वर्तमान गोरोइन के लिए एक स्टैक ट्रेस को प्रिंट करती है, रन-टाइम सिस्टम के लिए आंतरिक कार्यों को पूरा करती है, और फिर बाहर निकलने के कोड के साथ बाहर निकलती है। विफलता वर्तमान गोरोइन या विफलता नहीं होने पर सभी गोरआउट के लिए स्टैक का निशान लगाती है। रन-टाइम को आंतरिक।
ऐतिहासिक कारणों से, GOTRACEBACK सेटिंग्स 0, 1, और 2 क्रमशः, सभी और सिस्टम के लिए समानार्थक हैं।
रनटाइम / डीबग पैकेज का सेटट्रेसबैक फ़ंक्शन रन टाइम पर आउटपुट की मात्रा बढ़ाने की अनुमति देता है, लेकिन यह पर्यावरण चर द्वारा निर्दिष्ट राशि को कम नहीं कर सकता है। Https://golang.org/pkg/runtime/debug/#SetTraceback देखें ।