যদিও সঠিক উত্তর সরবরাহ করা হয়েছে যা GNU libc backtrace()
ফাংশন 1 কীভাবে ব্যবহার করতে হবে তা বর্ণনা করে এবং আমি আমার নিজস্ব উত্তর সরবরাহ করেছি যা কীভাবে সিগন্যাল হ্যান্ডলার থেকে ব্যাকট্রিজটি নিশ্চিত করতে হবে তা দোষ 2 এর প্রকৃত অবস্থানের দিকে নির্দেশ করে , আমি দেখতে পাই না ব্যাকট্রেস থেকে সি ++ প্রতীক আউটপুট ডিমেংলিংয়ের কোনও উল্লেখ ।
যখন একটি সি ++ প্রোগ্রাম থেকে ব্যাক প্রাপ্তির, আউটপুট মাধ্যমে চালানো যাবে c++filt
1 প্রতীক demangle অথবা ব্যবহার করে 1 সরাসরি।abi::__cxa_demangle
- 1 লিনাক্স এবং ওএস এক্স
নোট করুন
c++filt
এবং __cxa_demangle
এটি জিসিসি নির্দিষ্ট
- 2 লিনাক্স
নিম্নলিখিত সি ++ লিনাক্স উদাহরণটি আমার অন্যান্য উত্তরের মতো একই সংকেত হ্যান্ডলারটি ব্যবহার করে এবং দেখায় যে কীভাবে c++filt
প্রতীকগুলি ডিমেংল করতে ব্যবহার করা যেতে পারে।
কোড :
class foo
{
public:
foo() { foo1(); }
private:
void foo1() { foo2(); }
void foo2() { foo3(); }
void foo3() { foo4(); }
void foo4() { crash(); }
void crash() { char * p = NULL; *p = 0; }
};
int main(int argc, char ** argv)
{
// Setup signal handler for SIGSEGV
...
foo * f = new foo();
return 0;
}
আউটপুট ( ./test
):
signal 11 (Segmentation fault), address is (nil) from 0x8048e07
[bt]: (1) ./test(crash__3foo+0x13) [0x8048e07]
[bt]: (2) ./test(foo4__3foo+0x12) [0x8048dee]
[bt]: (3) ./test(foo3__3foo+0x12) [0x8048dd6]
[bt]: (4) ./test(foo2__3foo+0x12) [0x8048dbe]
[bt]: (5) ./test(foo1__3foo+0x12) [0x8048da6]
[bt]: (6) ./test(__3foo+0x12) [0x8048d8e]
[bt]: (7) ./test(main+0xe0) [0x8048d18]
[bt]: (8) ./test(__libc_start_main+0x95) [0x42017589]
[bt]: (9) ./test(__register_frame_info+0x3d) [0x8048981]
ডিমেংলেড আউটপুট ( ./test 2>&1 | c++filt
):
signal 11 (Segmentation fault), address is (nil) from 0x8048e07
[bt]: (1) ./test(foo::crash(void)+0x13) [0x8048e07]
[bt]: (2) ./test(foo::foo4(void)+0x12) [0x8048dee]
[bt]: (3) ./test(foo::foo3(void)+0x12) [0x8048dd6]
[bt]: (4) ./test(foo::foo2(void)+0x12) [0x8048dbe]
[bt]: (5) ./test(foo::foo1(void)+0x12) [0x8048da6]
[bt]: (6) ./test(foo::foo(void)+0x12) [0x8048d8e]
[bt]: (7) ./test(main+0xe0) [0x8048d18]
[bt]: (8) ./test(__libc_start_main+0x95) [0x42017589]
[bt]: (9) ./test(__register_frame_info+0x3d) [0x8048981]
নিম্নলিখিতটি আমার মূল উত্তর থেকে সিগন্যাল হ্যান্ডলারের উপর ভিত্তি করে তৈরি করে abi::__cxa_demangle
এবং চিহ্নগুলি কীভাবে পৃথক করা যায় তা প্রদর্শনের জন্য উপরের উদাহরণে সিগন্যাল হ্যান্ডলারটি প্রতিস্থাপন করতে পারে। এই সিগন্যাল হ্যান্ডলারটি উপরোক্ত উদাহরণের মতো একই ডিমেলযুক্ত আউটপুট উত্পাদন করে।
কোড :
void crit_err_hdlr(int sig_num, siginfo_t * info, void * ucontext)
{
sig_ucontext_t * uc = (sig_ucontext_t *)ucontext;
void * caller_address = (void *) uc->uc_mcontext.eip; // x86 specific
std::cerr << "signal " << sig_num
<< " (" << strsignal(sig_num) << "), address is "
<< info->si_addr << " from " << caller_address
<< std::endl << std::endl;
void * array[50];
int size = backtrace(array, 50);
array[1] = caller_address;
char ** messages = backtrace_symbols(array, size);
// skip first stack frame (points here)
for (int i = 1; i < size && messages != NULL; ++i)
{
char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;
// find parantheses and +address offset surrounding mangled name
for (char *p = messages[i]; *p; ++p)
{
if (*p == '(')
{
mangled_name = p;
}
else if (*p == '+')
{
offset_begin = p;
}
else if (*p == ')')
{
offset_end = p;
break;
}
}
// if the line could be processed, attempt to demangle the symbol
if (mangled_name && offset_begin && offset_end &&
mangled_name < offset_begin)
{
*mangled_name++ = '\0';
*offset_begin++ = '\0';
*offset_end++ = '\0';
int status;
char * real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
// if demangling is successful, output the demangled function name
if (status == 0)
{
std::cerr << "[bt]: (" << i << ") " << messages[i] << " : "
<< real_name << "+" << offset_begin << offset_end
<< std::endl;
}
// otherwise, output the mangled function name
else
{
std::cerr << "[bt]: (" << i << ") " << messages[i] << " : "
<< mangled_name << "+" << offset_begin << offset_end
<< std::endl;
}
free(real_name);
}
// otherwise, print the whole line
else
{
std::cerr << "[bt]: (" << i << ") " << messages[i] << std::endl;
}
}
std::cerr << std::endl;
free(messages);
exit(EXIT_FAILURE);
}