सी

2009-08-21 9 views
6

सी में सोलारिस 10 में किसी भी थ्रेड से कॉल स्टैक प्राप्त करें, मैं एक प्रक्रिया के भीतर मनमाने ढंग से थ्रेड से कॉल स्टैक प्राप्त करना चाहता हूं।सी

मेरे पास कई कार्यकर्ता धागे और एक धागा है जो उन्हें सभी को तंग लूप और डेडलॉक्स का पता लगाने के लिए निगरानी करता है। जिस फ़ंक्शन को मैं कार्यान्वित करना चाहता हूं वह मॉनिटरिंग थ्रेड के लिए "लटका" थ्रेड से कॉल स्टैक को प्रिंट करने से पहले कई बार प्रिंट करता है।

मुझे पता है कि निगरानी थ्रेड निष्पादित पस्टैक (सिस्टम() या फोर्किंग द्वारा) को कार्यान्वित करके इसे कैसे कार्यान्वित किया जाए। लेकिन मैं इस समारोह को सी में लागू करने में सक्षम होना चाहता हूं। क्या ऐसा करने का कोई तरीका है?

मुझे पता है कि थ्रेड को अपने ओडब्ल्यूएन कॉल स्टैक को कैसे स्टैक चलाना है, जो उपयोगी है अगर यह एक जोर से हिट करता है, लेकिन एक ही प्रक्रिया के भीतर किसी अन्य धागे के लिए ऐसा नहीं करना है।

किसी भी मदद के लिए धन्यवाद। निकबी

उत्तर

3

यदि आप जीसीसी का उपयोग कर रहे हैं तो आप इनबिल्ट फ़ंक्शन __builtin_return_address का उपयोग कर सकते हैं। शून्य * __builtin_return_address (हस्ताक्षरित int स्तर)

फ़ंक्शन उस फ़ंक्शन का पता देता है जिस पर फ़ंक्शन कहा जाता है। यानी समारोह के कॉलर।

स्तर निर्दिष्ट करता है कि कितने स्तर हैं। 0 का मतलब है वर्तमान फ़ंक्शन 1 का अर्थ है कॉलर, 2 का मतलब कॉलर्स कॉलर है। निम्नलिखित उदाहरण उपयोग प्रदान करेगा। फ़ंक्शन के पते प्रिंट करके, कॉल स्टैक निर्धारित किया जा सकता है।

int calla() 
{ 
    printf("Inside calla\n"); 
    printf("A1=%x\n",__builtin_return_address (0)); 
    printf("A2=%x\n",__builtin_return_address (1)); 
    printf("A3=%x\n",__builtin_return_address (2)); 
} 
int callb() 
{ 
    printf("Inside callb\n"); 
    calle(); 
    printf("B1=%x\n",__builtin_return_address (0)); 
    printf("B2=%x\n",__builtin_return_address (1)); 
    printf("B3=%x\n",__builtin_return_address (2)); 
} 
int callc() 
{ 
    printf("Inside callc\n"); 
    printf("C1=%x\n",__builtin_return_address (0)); 
    printf("C2=%x\n",__builtin_return_address (1)); 
    printf("C3=%x\n",__builtin_return_address (2)); 
} 
int calld() 
{ 
    printf("Inside calld\n"); 
    printf("D1=%x\n",__builtin_return_address (0)); 
    printf("D2=%x\n",__builtin_return_address (1)); 
    printf("D3=%x\n",__builtin_return_address (2)); 
} 
int calle() 
{ 
    printf("Inside calle\n"); 
    printf("E1=%x\n",__builtin_return_address (0)); 
    printf("E2=%x\n",__builtin_return_address (1)); 
    printf("E3=%x\n",__builtin_return_address (2)); 
} 
main() 
{ 
    printf("Address of main=%x calla=%x callb=%x callc=%x calld=%x calle=%x\n",main,calla,callb,callc,calld,calle); 
    calla(); 
    callb(); 
    calld(); 
} 
+0

लेकिन यह कैसे एक थ्रेड को किसी अन्य थ्रेड से कॉल स्टैक प्राप्त करने की अनुमति देता है? – NickB

4

आप walkcontext() का उपयोग ढेर चलने के लिए, dladdr()/dladdr1() का उपयोग कर नाम से कार्य करने के पतों कन्वर्ट करने के लिए कर सकते हैं। walkcontext() धागे के लिए ucontext लेता है। यदि आपके पास उस धागे का सहयोग नहीं है तो आप थ्रेड को रोककर इसके लिए एक ucontext प्राप्त कर सकते हैं (उदा। PCTWSTOP के साथ) और फिर /proc/self/lstatus से प्राप्त उस थ्रेड के लिए lwpstatus संरचना के pr_oldcontext फ़ील्ड से अपना पता पढ़ सकते हैं।