मैं विंडोज निष्पादन योग्य में कॉल स्टैक प्राप्त करने के लिए संघर्ष कर रहा हूं। मैंने कॉल स्टैक प्राप्त करने के कई अलग-अलग तरीकों की कोशिश की है। निम्नलिखित कुछ उदाहरण हैं। ध्यान दें कि मैंने उन्हें थोड़ा सा संशोधित किया है और उन्हें समझने में आसान बनाने के लिए त्रुटि प्रबंधन को हटा दिया है, इसलिए वे संकलित नहीं हो सकते हैं। मुझे लगता है आपको बात समझ में आ गयी है।रिलीज में कॉल स्टैक प्राप्त करने में समस्याएं
आसान तरीका:
const int max_entries = 10;
void *entries[max_entries];
return CaptureStackBackTrace(0, max_entries, entries, 0);
निम्न स्तर रास्ता:
const int max_entries = 10;
void *entries[max_entries];
void **frame = 0;
__asm { mov frame, ebp }
unsigned int i = 0;
while(frame && i < max_entries) {
entries[i++] = frame[1];
frame = (void **)frame[0];
}
संगत तरीका:
void *entries[max_entries];
CONTEXT context;
RtlCaptureContext(&context);
STACKFRAME64 stack_frame;
ZeroMemory(&stack_frame, sizeof(STACKFRAME64));
stack_frame.AddrPC.Offset = context.Eip;
stack_frame.AddrPC.Mode = AddrModeFlat;
stack_frame.AddrFrame.Offset = context.Ebp;
stack_frame.AddrFrame.Mode = AddrModeFlat;
stack_frame.AddrStack.Offset = context.Esp;
stack_frame.AddrStack.Mode = AddrModeFlat;
unsigned int num_frames = 0;
while (true) {
if (!StackWalk64(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(),
GetCurrentThread(), &stack_frame, &context, NULL,
SymFunctionTableAccess64, SymGetModuleBase64, NULL))
break;
if (stack_frame.AddrPC.Offset == 0)
break;
entries[num_frames++] = reinterpret_cast<void *>(stack_frame.AddrPC.Offset);
}
मेरे समस्या यह है कि वे एक unoptimized निर्माण में काम है, लेकिन पूर्ण अनुकूलन के साथ नहीं। क्या होता है कि मुझे एक टूटी हुई प्रविष्टि मिलती है और फिर वे अपने लूप से बाहर निकलते हैं। डीबग में मुझे पूर्ण कॉल स्टैक मिलता है और जब मैं बाद में प्रतीकों को देखता हूं, तो यह सब सही है।
मुझे समझ में नहीं आता कि यह काम सभी कार्यों में कैसे करना मुश्किल हो सकता है जब डीबगर इसे हर समय करता है। मैं विशेष रूप से कह सकता हूं कि फ्रेम पॉइंटर्स कोड पीढ़ी में छोड़े नहीं जाते हैं। मैं पहले डीबग के लिए निर्माण करता हूं और फिर केवल ऑप्टिमाइज़ेशन को पूर्ण ऑप्टिमाइज़ेशन में बदलता हूं और कॉल स्टैक विफलता को पुन: पेश करने के लिए पुनर्निर्माण करता हूं।
किसी समाधान के लिए किसी भी संकेत की सराहना की जाएगी।
/जोनास
आप फ्रेम सूचक अनुकूलन के साथ संकलित नहीं कर रहे हैं, है ना? –
फ़्रेम पॉइंटर्स कोड जनरेशन में छोड़े नहीं जाते हैं, यदि आपका यही मतलब है। –