Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
failpoint — Go के लिए फॉल्ट-इंजेक्शन लाइब्रेरी जो एनवायरनमेंट वेरिएबल्स के माध्यम से पैनिक्स, स्लीप्स, रिटर्न्स और कंडीशनल एरर पाथ को ट्रिगर करने के लिए रनटाइम-नियंत्रणीय फेलपॉइंट्स जोड़ती है। | Kitploit
उपकरण/GitHubGitHub/pingcap/failpoint
सामान्य उपयोगिताएँडीबगर्सकैओस इंजीनियरिंग
GitHubpingcap/failpoint

failpoint

Go के लिए फॉल्ट-इंजेक्शन लाइब्रेरी जो एनवायरनमेंट वेरिएबल्स के माध्यम से पैनिक्स, स्लीप्स, रिटर्न्स और कंडीशनल एरर पाथ को ट्रिगर करने के लिए रनटाइम-नियंत्रणीय फेलपॉइंट्स जोड़ती है।

रिपॉजिटरी देखें
8946712 दिन पहलेKitploit द्वारा समीक्षित

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

failpoint

LICENSE Language Go Report Card Build Status Coverage Status Mentioned in Awesome Go

Golang के लिए failpoints का एक कार्यान्वयन। फेल पॉइंट्स (fail points) का उपयोग कोड पॉइंट्स जोड़ने के लिए किया जाता है जहाँ त्रुटियाँ उपयोगकर्ता-नियंत्रित तरीके से इंजेक्ट की जा सकती हैं। फेल पॉइंट एक कोड स्निपेट है जो केवल तब निष्पादित होता है जब संबंधित failpoint सक्रिय हो।

Quick Start (use failpoint-ctl)

  1. failpoint-ctl को सोर्स से बनाएँ

    root@kitploit:~
    git clone https://github.com/pingcap/failpoint.git
    cd failpoint
    make
    ls bin/failpoint-ctl
    
  2. अपने प्रोग्राम में failpoints इंजेक्ट करें, उदा.:

    root@kitploit:~
    package main
    
    import "github.com/pingcap/failpoint"
    
    func main() {
        failpoint.Inject("testPanic", func() {
            panic("failpoint triggerd")
        })
    }
    
  3. अपने कोड को failpoint-ctl enable के साथ रूपांतरित करें

  4. go build के साथ बनाएँ

  5. GO_FAILPOINTS पर्यावरण चर के साथ failpoints सक्षम करें

    root@kitploit:~
    GO_FAILPOINTS="main/testPanic=return(true)" ./your-program
    

    नोट: GO_FAILPOINTS InjectCall प्रकार के मार्कर के साथ काम नहीं करता है।

  6. यदि आप परीक्षण चलाने के लिए go run का उपयोग करते हैं, तो अपने कमांड में जनरेट की गई को जोड़ना न भूलें, जैसे:

Quick Start (use failpoint-toolexec)

  1. failpoint-toolexec को सोर्स से बनाएँ

    root@kitploit:~
    git clone https://github.com/pingcap/failpoint.git
    cd failpoint
    make
    ls bin/failpoint-toolexec
    
  2. अपने प्रोग्राम में failpoints इंजेक्ट करें, उदा.:

    root@kitploit:~
    package main
    
    import "github.com/pingcap/failpoint"
    
    func main() {
        failpoint.Inject("testPanic", func() {
            panic("failpoint triggerd")
        })
    }
    
  3. failpoint-toolexec के बिना कैश मिश्रण से बचने के लिए एक अलग बिल्ड कैश का उपयोग करें, और बनाएँ

    GOCACHE=/tmp/failpoint-cache go build -toolexec path/to/failpoint-toolexec

  4. GO_FAILPOINTS पर्यावरण चर के साथ failpoints सक्षम करें

    root@kitploit:~
    GO_FAILPOINTS="main/testPanic=return(true)" ./your-program
    
  5. आप go run या go test का भी उपयोग कर सकते हैं, जैसे:

    root@kitploit:~
    GOCACHE=/tmp/failpoint-cache GO_FAILPOINTS="main/testPanic=return(true)" go run -toolexec path/to/failpoint-toolexec your-program.go
    

Design principles

  • Failpoint को मान्य Golang कोड में परिभाषित करें, टिप्पणियों या किसी और चीज़ में नहीं

  • Failpoint की कोई अतिरिक्त लागत नहीं होती

    • नियमित लॉजिक पर प्रभाव नहीं डालेगा
    • नियमित कोड के प्रदर्शन में गिरावट नहीं लाएगा
    • Failpoint कोड अंतिम बाइनरी में दिखाई नहीं देगा
  • Failpoint रूटीन लिखने/पढ़ने योग्य है और कंपाइलर द्वारा जाँचा जाना चाहिए

  • Failpoint परिभाषा द्वारा जनरेट किया गया कोड पढ़ने में आसान है

  • इंजेक्टिंग कोड के साथ लाइन नंबर समान रखें (डिबग करना आसान)

  • context.Context के साथ समानांतर परीक्षणों का समर्थन करें

Key concepts

  • Failpoint

    फेलपॉइंट एक कोड स्निपेट है जो केवल तब निष्पादित होता है जब संबंधित failpoint सक्रिय हो। यदि failpoint.Disable("failpoint-name-for-demo") निष्पादित किया जाता है तो क्लोज़र कभी निष्पादित नहीं होगा।

    root@kitploit:~
    var outerVar = "declare in outer scope"
    failpoint.Inject("failpoint-name-for-demo", func(val failpoint.Value) {
        fmt.Println("unit-test", val, outerVar)
    })
    
  • Marker functions

    • यह सिर्फ एक खाली फ़ंक्शन है

      • रीराइटर को समानता वाले स्टेटमेंट के साथ रीराइट करने का संकेत देने के लिए
      • रीराइट नियम के रूप में कुछ पैरामीटर प्राप्त करने के लिए
      • यह कंपाइल समय पर इनलाइन होगा और बाइनरी में कुछ भी एमिट नहीं करेगा (शून्य लागत)
      • बाहरी स्कोप के चर कैप्चर करके क्लोज़र में एक्सेस किए जा सकते हैं, और परिवर्तित कोड अभी भी मान्य है क्योंकि सभी कैप्चर किए गए चर IF स्टेटमेंट के बाहरी स्कोप में स्थित होते हैं।
    • यह लिखना/पढ़ना आसान है

    • Failpoints के लिए एक कंपाइलर जाँच प्रस्तुत करता है जो failpoint कोड अमान्य होने पर नियमित मोड में संकलित नहीं हो सकता

  • Marker funtion list

    • func Inject(fpname string, fpblock func(val Value)) {}
    • func InjectContext(fpname string, ctx context.Context, fpblock func(val Value)) {}
    • func InjectCall(fpname string, args ...any) {}
    • func Break(label ...string) {}

How to inject a failpoint to your program

  • आप कॉल साइट पर failpoint इंजेक्ट करने के लिए failpoint.Inject को कॉल कर सकते हैं, जहाँ failpoint-name failpoint को ट्रिगर करने के लिए उपयोग किया जाता है और failpoint-closure को IF स्टेटमेंट के बॉडी के रूप में विस्तारित किया जाएगा।

    root@kitploit:~
    failpoint.Inject("failpoint-name", func(val failpoint.Value) {
        failpoint.Return("unit-test", val)
    })
    

    परिवर्तित कोड इस प्रकार दिखता है:

    root@kitploit:~
    if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
        return "unit-test", val
    }
    
  • failpoint.Value वह मान है जो failpoint.Enable("failpoint-name", "return(5)") द्वारा पारित किया जाता है, जिसे अनदेखा किया जा सकता है।

    root@kitploit:~
    failpoint.Inject("failpoint-name", func(_ failpoint.Value) {
        fmt.Println("unit-test")
    })
    

    OR

    root@kitploit:~
    failpoint.Inject("failpoint-name", func() {
        fmt.Println("unit-test")
    })
    

Some complicated failpoints demo

  • IF इनिशियल स्टेटमेंट या CONDITIONAL एक्सप्रेशन में failpoint इंजेक्ट करें

    root@kitploit:~
    if a, b := func() {
        failpoint.Inject("failpoint-name", func(val failpoint.Value) {
            fmt.Println("unit-test", val)
        })
    }, func() int { return rand.Intn(200) }(); b > func() int {
        failpoint.Inject("failpoint-name", func(val failpoint.Value) int {
            return val.(int)
        })
        return rand.Intn(3000)
    }() && b < func() int {
        failpoint.Inject("failpoint-name-2", func(val failpoint.Value) {
            return rand.Intn(val.(int))
        })
        return rand.Intn(6000)
    }() {
        a()
        failpoint.Inject("failpoint-name-3", func(val failpoint.Value) {
            fmt.Println("unit-test", val)
        })
    }
    

    उपरोक्त कोड ब्लॉक कुछ इस प्रकार जनरेट करेगा:

    root@kitploit:~
    if a, b := func() {
        if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
            fmt.Println("unit-test", val)
        }
    }, func() int { return rand.Intn(200) }(); b > func() int {
        if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
            return val.(int)
        }
        return rand.Intn(3000)
    }() && b < func() int {
        if val, ok := failpoint.Eval(_curpkg_("failpoint-name-2")); ok {
            return rand.Intn(val.(int))
        }
        return rand.Intn(6000)
    }() {
        a()
        if val, ok := failpoint.Eval(_curpkg_("failpoint-name-3")); ok {
            fmt.Println("unit-test", val)
        }
    }
    
  • SELECT स्टेटमेंट में failpoint इंजेक्ट करें ताकि failpoint सक्रिय होने पर यह एक CASE को ब्लॉक कर दे

Failpoint name best practice

जैसा कि आप ऊपर देखते हैं, _curpkg_ स्वचालित रूप से failpoint.Eval कॉल में मूल failpoint नाम को लपेटेगा। आप _curpkg_ को एक मैक्रो के रूप में सोच सकते हैं जो failpoint नाम में स्वचालित रूप से वर्तमान पैकेज पथ जोड़ता है। उदाहरण के लिए,

root@kitploit:~
package ddl // which parent package is `github.com/pingcap/tidb`

func demo() {
	// _curpkg_("the-original-failpoint-name") will be expanded as `github.com/pingcap/tidb/ddl/the-original-failpoint-name`
	if val, ok := failpoint.Eval(_curpkg_("the-original-failpoint-name")); ok {...}
}

आपको अपने एप्लिकेशन में _curpkg_ के बारे में चिंता करने की आवश्यकता नहीं है। यह failpoint-ctl enable चलाने के बाद स्वचालित रूप से जनरेट होता है और failpoint-ctl disable के साथ हटा दिया जाता है।

चूँकि एक पैकेज में सभी failpoints एक ही नामस्थान साझा करते हैं, हमें नाम संघर्ष से बचने के लिए सावधान रहने की आवश्यकता है। इस स्थिति को सुधारने के लिए कुछ अनुशंसित नामकरण नियम हैं।

  • वर्तमान सबपैकेज में नाम अद्वितीय रखें

  • Failpoint के लिए एक स्व-व्याख्यात्मक नाम का उपयोग करें

    आप पर्यावरण चर द्वारा failpoints सक्षम कर सकते हैं

    root@kitploit:~
    GO_FAILPOINTS="github.com/pingcap/tidb/ddl/renameTableErr=return(100);github.com/pingcap/tidb/planner/core/illegalPushDown=return(true);github.com/pingcap/pd/server/schedulers/balanceLeaderFailed=return(true)"
    

Implementation details

  1. मार्कर फ़ंक्शन का एक समूह परिभाषित करें
  2. इम्पोर्ट्स को पार्स करें और ऐसी सोर्स फ़ाइल को प्रून करें जो failpoint इम्पोर्ट नहीं करती
  3. मार्कर फ़ंक्शन कॉल खोजने के लिए AST को ट्रैवर्स करें
  4. मार्कर फ़ंक्शन कॉल को एक IF स्टेटमेंट के साथ फिर से लिखा जाएगा, जो यह निर्धारित करने के लिए failpoint.Eval को कॉल करता है कि failpoint सक्रिय है या नहीं और यदि failpoint सक्षम है तो failpoint कोड निष्पादित करता है।

rewrite-demo

Acknowledgments

  • प्रारंभिक कार्यान्वयन प्रदान करने के लिए gofail को धन्यवाद।
टूल डाउनलोड करें
binding__failpoint_binding__.go
root@kitploit:~
GO_FAILPOINTS="main/testPanic=return(true)" go run your-program.go binding__failpoint_binding__.go
  • func Goto(label string) {}
  • func Continue(label ...string) {}
  • func Fallthrough() {}
  • func Return(results ...interface{}) {}
  • func Label(label string) {}
  • Supported failpoint environment variable

    failpoint को निम्न पैटर्न वाले निर्यात पर्यावरण चर द्वारा सक्षम किया जा सकता है, जो freebsd failpoint SYSCTL VARIABLES के समान है।

    नोट: InjectCall को पर्यावरण चर द्वारा सक्षम नहीं किया जा सकता।

    root@kitploit:~
    [<percent>%][<count>*]<type>[(args...)][-><more terms>]
    

    तर्क निर्दिष्ट करता है कि कौन सी क्रिया करनी है; यह निम्न में से एक हो सकता है:

    • off: कोई कार्रवाई नहीं करें (failpoint कोड ट्रिगर नहीं करता)
    • return: निर्दिष्ट तर्क के साथ failpoint ट्रिगर करें
    • sleep: निर्दिष्ट मिलीसेकंड के लिए सोएं
    • panic: पैनिक करें
    • break: gdb निष्पादित करें और डीबगर में ब्रेक करें
    • print: इंजेक्ट वेरिएबल के लिए failpoint पथ प्रिंट करें
    • pause: पॉज़ तब तक रुकेगा जब तक failpoint अक्षम न हो जाए
  • और परिवर्तित कोड इस प्रकार दिखता है:

    root@kitploit:~
    if _, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
        fmt.Println("unit-test")
    }
    
  • इसके अलावा, failpoint क्लोज़र एक फ़ंक्शन हो सकता है जो context.Context लेता है। आप context.Context के साथ कुछ अनुकूलित चीज़ें कर सकते हैं जैसे नियंत्रित करना कि समानांतर परीक्षणों या अन्य मामलों में failpoint सक्रिय है या नहीं। उदाहरण के लिए,

    root@kitploit:~
    failpoint.InjectContext(ctx, "failpoint-name", func(val failpoint.Value) {
        fmt.Println("unit-test", val)
    })
    

    परिवर्तित कोड इस प्रकार दिखता है:

    root@kitploit:~
    if val, _err_ := failpoint.EvalContext(ctx, _curpkg_("failpoint-name")); _err_ == nil {
        fmt.Println("unit-test", val)
    }
    
  • आप context.Context को अनदेखा कर सकते हैं, और यह ऊपर दिए गए गैर-संदर्भ संस्करण के समान कोड जनरेट करेगा। उदाहरण के लिए,

    root@kitploit:~
    failpoint.InjectContext(nil, "failpoint-name", func(val failpoint.Value) {
        fmt.Println("unit-test", val)
    })
    

    बन जाता है

    root@kitploit:~
    if val, _err_ := failpoint.EvalContext(nil, _curpkg_("failpoint-name")); _err_ == nil {
        fmt.Println("unit-test", val)
    }
    
  • आप फ़ंक्शन कॉल इंजेक्ट करने के लिए failpoint.InjectCall का उपयोग कर सकते हैं, इस प्रकार के मार्कर को केवल failpoint.EnableCall का उपयोग करके सक्षम किया जा सकता है और इसे InjectCall कॉल साइट के समान प्रोसेस में कॉल किया जाना चाहिए। इस मार्कर का उपयोग करके, आप failpoint कोड को अपने सोर्स कोड को प्रदूषित करने से बचा सकते हैं। उदाहरण देखें।

  • आप failpoint.WithHook द्वारा failpoint को नियंत्रित कर सकते हैं

    root@kitploit:~
    func (s *dmlSuite) TestCRUDParallel() {
        sctx := failpoint.WithHook(context.Backgroud(), func(ctx context.Context, fpname string) bool {
            return ctx.Value(fpname) != nil // Determine by ctx key
        })
        insertFailpoints = map[string]struct{} {
            "insert-record-fp": {},
            "insert-index-fp": {},
            "on-duplicate-fp": {},
        }
        ictx := failpoint.WithHook(context.Backgroud(), func(ctx context.Context, fpname string) bool {
            _, found := insertFailpoints[fpname] // Only enables some failpoints.
            return found
        })
        deleteFailpoints = map[string]struct{} {
            "tikv-is-busy-fp": {},
            "fetch-tso-timeout": {},
        }
        dctx := failpoint.WithHook(context.Backgroud(), func(ctx context.Context, fpname string) bool {
            _, found := deleteFailpoints[fpname] // Only disables failpoints. 
            return !found
        })
        // other DML parallel test cases.
        s.RunParallel(buildSelectTests(sctx))
        s.RunParallel(buildInsertTests(ictx))
        s.RunParallel(buildDeleteTests(dctx))
    }
    
  • यदि आप लूप संदर्भ में failpoint का उपयोग करते हैं, तो शायद आप अन्य मार्कर फ़ंक्शन का उपयोग करेंगे।

    root@kitploit:~
    failpoint.Label("outer")
    for i := 0; i < 100; i++ {
        inner:
            for j := 0; j < 1000; j++ {
                switch rand.Intn(j) + i {
                case j / 5:
                    failpoint.Break()
                case j / 7:
                    failpoint.Continue("outer")
                case j / 9:
                    failpoint.Fallthrough()
                case j / 10:
                    failpoint.Goto("outer")
                default:
                    failpoint.Inject("failpoint-name", func(val failpoint.Value) {
                        fmt.Println("unit-test", val.(int))
                        if val == j/11 {
                            failpoint.Break("inner")
                        } else {
                            failpoint.Goto("outer")
                        }
                    })
            }
        }
    }
    

    उपरोक्त कोड ब्लॉक निम्न कोड जनरेट करेगा:

    root@kitploit:~
    outer:
        for i := 0; i < 100; i++ {
        inner:
            for j := 0; j < 1000; j++ {
                switch rand.Intn(j) + i {
                case j / 5:
                    break
                case j / 7:
                    continue outer
                case j / 9:
                    fallthrough
                case j / 10:
                    goto outer
                default:
                    if val, _err_ := failpoint.Eval(_curpkg_("failpoint-name")); _err_ == nil {
                        fmt.Println("unit-test", val.(int))
                        if val == j/11 {
                            break inner
                        } else {
                            goto outer
                        }
                    }
                }
            }
        }
    
  • आपको संदेह हो सकता है कि हम failpoint मार्कर फ़ंक्शन का उपयोग करने के बजाय सीधे label, break, continue, और fallthrough का उपयोग क्यों नहीं करते।

    • Golang में आइडेंटिफ़ायर या लेबल जैसे किसी भी अप्रयुक्त प्रतीक की अनुमति नहीं है। यदि कोई लेबल केवल failpoint क्लोज़र में उपयोग किया जाता है तो यह अमान्य होगा। उदाहरण के लिए,

      root@kitploit:~
      label1: // compiler error: unused label1
          failpoint.Inject("failpoint-name", func(val failpoint.Value) {
              if val.(int) == 1000 {
                  goto label1 // illegal to use goto here
              }
              fmt.Println("unit-test", val)
          })
      
    • break और continue का उपयोग केवल लूप संदर्भ में किया जा सकता है, जो Golang कोड में कानूनी नहीं है यदि हम उन्हें सीधे क्लोज़र में उपयोग करते हैं।

  • root@kitploit:~
    func (s *StoreService) ExecuteStoreTask() {
        select {
        case <-func() chan *StoreTask {
            failpoint.Inject("priority-fp", func(_ failpoint.Value) {
                return make(chan *StoreTask)
            })
            return s.priorityHighCh
        }():
            fmt.Println("execute high priority task")
    
        case <- s.priorityNormalCh:
            fmt.Println("execute normal priority task")
    
        case <- s.priorityLowCh:
            fmt.Println("execute normal low task")
        }
    }
    

    उपरोक्त कोड ब्लॉक कुछ इस प्रकार जनरेट करेगा:

    root@kitploit:~
    func (s *StoreService) ExecuteStoreTask() {
        select {
        case <-func() chan *StoreTask {
            if _, ok := failpoint.Eval(_curpkg_("priority-fp")); ok {
                return make(chan *StoreTask)
            })
            return s.priorityHighCh
        }():
            fmt.Println("execute high priority task")
    
        case <- s.priorityNormalCh:
            fmt.Println("execute normal priority task")
    
        case <- s.priorityLowCh:
            fmt.Println("execute normal low task")
        }
    }
    
  • SWITCH CASE आर्म्स को गतिशील रूप से विस्तारित करने के लिए failpoint इंजेक्ट करें

    root@kitploit:~
    switch opType := operator.Type(); {
    case opType == "balance-leader":
        fmt.Println("create balance leader steps")
    
    case opType == "balance-region":
        fmt.Println("create balance region steps")
    
    case opType == "scatter-region":
        fmt.Println("create scatter region steps")
    
    case func() bool {
        failpoint.Inject("dynamic-op-type", func(val failpoint.Value) bool {
            return strings.Contains(val.(string), opType)
        })
        return false
    }():
        fmt.Println("do something")
    
    default:
        panic("unsupported operator type")
    }
    

    उपरोक्त कोड ब्लॉक कुछ इस प्रकार जनरेट करेगा:

    root@kitploit:~
    switch opType := operator.Type(); {
    case opType == "balance-leader":
        fmt.Println("create balance leader steps")
    
    case opType == "balance-region":
        fmt.Println("create balance region steps")
    
    case opType == "scatter-region":
        fmt.Println("create scatter region steps")
    
    case func() bool {
        if val, ok := failpoint.Eval(_curpkg_("dynamic-op-type")); ok {
            return strings.Contains(val.(string), opType)
        }
        return false
    }():
        fmt.Println("do something")
    
    default:
        panic("unsupported operator type")
    }
    
  • More complicated failpoints

    • कुछ और जटिल failpoint साइट्स हैं जिनमें इंजेक्ट किया जा सकता है
      • लूप इनिशियल स्टेटमेंट, CONDITIONAL एक्सप्रेशन और POST स्टेटमेंट के लिए
      • RANGE स्टेटमेंट के लिए
      • SWITCH इनिशियल स्टेटमेंट
      • …
    • आप किसी भी स्थान पर फ़ंक्शन कॉल कर सकते हैं