2017-06-28 18 views
5

समस्या निवारण कारण के लिए, मैं वर्तमान में चल रहे फ़ंक्शन के कॉलर स्टैक को पुनः प्राप्त और प्रिंट करने में सक्षम होना चाहता हूं। मैं निम्नलिखित की कोशिश की है:वर्तमान में चल रहे फ़ंक्शन के ढेर के स्टैक ट्रेस को मैं कैसे पुनर्प्राप्त कर सकता हूं?

/******************************************************************************* 
* * 
* * xxxTracePrint - stack trace print function 
* * 
* * RETURNS: OK or ERROR 
* */ 

static void xxxTracePrint 
    (
     INSTR *caller, 
      int func, 
       int nargs, 
        int *args 
         ) 
{ 
    char buf [250]; 
    int ix; 
    int len = 0; 

    len += sprintf (&buf [len], "%#10x: %#10x (", (int)caller, func); 
    for (ix = 0; ix < nargs; ix++) { 
     if (ix != 0) 
      len += sprintf (&buf [len], ", "); 
     len += sprintf (&buf [len], "%#x", args [ix]); 
    } 

    len += sprintf (&buf [len], ")\n"); 

    printf (buf); 
} 

/******************************************************************************* 
* * 
* * xxxTrace - stack trace 
* * 
* * RETURNS: OK or ERROR 
* */ 

int xxxTrace(int tcb) 
{ 
    REG_SET regs; 

    if (tcb == 0) 
     return (ERROR); 

    taskRegsGet (tcb, &regs); 
    trcStack (&regs, (FUNCPTR) xxxTracePrint, tcb); 

    return (OK); 
} 

void DbgTest(void) 
{ 
    xxxTrace(taskIdSelf()); 
} 

लेकिन मैं मिलता है:

JPAX-DP> DbgTest 
trcStack aborted: error in top frame 
value = 0 = 0x0 

यह और भी संभव है? मैं यह कैसे कर सकता हूँ? मैंने देखा, taskRegsGet() के लिए, वे कहते हैं:

यह दिनचर्या ही काम करता है अच्छी तरह से करता है, तो काम के लिए एक स्थिर, गैर निष्पादित करने राज्य में माना जाता है। उदाहरण के लिए, स्व-परीक्षा सलाह नहीं दी जाती है, परिणाम न अप्रत्याशित हैं।

लेकिन मुझे अन्य विधि क्या लागू करनी चाहिए?

संकलक diab और सीपीयू मेहराब है powerpc

+0

आप पश्व-अनुरेखन उपयोग कर सकते हैं() , यदि यह vxworks में उपलब्ध है, तो इसके मैन पेज में एक कामकाजी उदाहरण भी है – Pras

+0

@ हैरी क्या आपके पास surce code और WindRiver Workbench तक पहुंच है? – cerr

+0

@cerr हाँ मेरे पास स्रोत कोड और विंड्रिवर वर्कबेंच – Harry

उत्तर

1

आपने बताया कि taskRegsGet() का उल्लेख है कि वर्तमान में चल रहे कार्य से कॉल करने की सलाह नहीं दी जाती है। हालांकि मैंने किसी को 'बल संदर्भ सहेजें' टिप्पणी के साथ taskDelay (1) का उपयोग करके किसी को देखा है। मैं इसके लिए क्रेडिट नहीं ले जा सकते, और न ही मुझे पता है कि यह कैसे विश्वसनीय है करते हैं, या क्या दुष्प्रभाव यह हो सकता है, लेकिन यह वर्तमान कार्य के बारे में सही जानकारी प्राप्त करने के लिए मदद कर सकता है:

taskDelay (1);  /* Force context save */ 
taskRegsGet (0, &regs); /* 0 task-id for myself */ 
trcStack (&regs, NULL, 0); /* NULL function pointer for default print fcn, 0 task-id for myself */ 
1

अपने संकलक जीसीसी और अपने वास्तुकला परमिट के बुला सम्मेलनों है यदि यह (x86 पहले जो मन में आता जा रहा है), मैं __builtin_return_address का उपयोग कर की सलाह देते हैं (अहस्ताक्षरित int स्तर)। अधिक जानकारी यहां मिल सकती है: https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html

+0

दुर्भाग्य से, मैं पावरपीसी और डायब कंपाइलर पर हूं – cerr

+0

जबकि अधिक भारी हाथ और आवश्यकता है एक पुनरावृत्ति प्रक्रिया आप लिंक रजिस्टर्स सामग्री को एक सी वैरिएबल में स्थानांतरित करने के लिए कुछ रेखांकित असेंबली लिख सकते हैं जिसे आप प्रिंट कर सकते हैं। खराब दस्तावेज़ इनलाइन असेंबली सिंटैक्स डायब समर्थन का उपयोग करने के अलावा इस दृष्टिकोण के मुख्य नकारात्मक पक्ष यह है कि आप केवल वर्तमान फ़ंक्शन के कॉलर को ही ढूंढ सकते हैं। अगली कॉल प्राप्त करने के लिए आपको लिंक रजिस्ट्रार सामग्री प्राप्त करने के लिए कॉलिंग फ़ंक्शन को संशोधित करना होगा। मैंने इसे एआरएम और पीपीसी कार्ड में उपयोग किया है, लेकिन यह अंतिम उपाय की तकनीक है। – vxWizard

+0

क्या आप कार्य पर "टीटी" कर सकते हैं? vxWorks खोल पर टीटी । कार्य के लिए नीचे दिए गए विकल्पों को सेट करने का प्रयास करें और देखें कि क्या यह "taskOptionsSet , 2, 0" में सहायता करता है। –

संबंधित मुद्दे

 संबंधित मुद्दे