আপনি যদি স্ট্যাক ট্রেসটি সেগফোল্ট করে মুদ্রণ করতে লিনাক্সে কোনও প্রোগ্রাম পেতে পারেন?


20

আমি যদি শেল থেকে কোনও প্রোগ্রাম চালনা করি এবং এটি সিগফল্ট করে:

$ buggy_program
Segmentation fault

এটি আমাকে বলবে, তবে, ব্যাকট্রিজ প্রিন্ট করার জন্য প্রোগ্রামগুলি পাওয়ার উপায় আছে, সম্ভবত এই জাতীয় কিছু চালিয়ে:

$ print_backtrace_if_segfault buggy_program
Segfault in main.c:35
(rest of the backtrace)

আমি বরং এই জাতীয় তথ্যের জন্য স্ট্রেস বা ltrace ব্যবহার করব না, কারণ তারা যে কোনও উপায়ে মুদ্রণ করবে ...

উত্তর:


25

আরও ভাল উপায় থাকতে পারে তবে এই ধরণের এটি স্বয়ংক্রিয়ভাবে চলে।

নিম্নলিখিতটি লিখুন ~/backtrace:

backtrace
quit

seg_wrapper.shআপনার পাথের ডিরেক্টরিতে ডাকা একটি স্ক্রিপ্টে এটি রাখুন :

#!/bin/bash
ulimit -c unlimited
"$@"
if [[ $? -eq 139 ]]; then
    gdb -q $1 core -x ~/backtrace
fi

ulimitকমান্ড এটা তোলে তাই কোর ডাম্প করা হয়। "$@"স্ক্রিপ্টে দেওয়া আর্গুমেন্টগুলি হ'ল এটি আপনার প্রোগ্রাম এবং এর যুক্তি। $?প্রস্থান স্থিতি ধরে রেখেছে, 139 টি সেগফল্টের জন্য আমার মেশিনের জন্য ডিফল্ট প্রস্থান স্থিতি বলে মনে হচ্ছে।

জন্য gdb, -qমানে শান্ত (কোন ইন্ট্রো বার্তা), এবং -xবলে gdbএটা দেওয়া ফাইলে কমান্ড চালানো।

ব্যবহার

সুতরাং এটি ব্যবহার করতে আপনি ঠিক করবেন:

seg_wrapper.sh ./mycommand and its arguments 

হালনাগাদ

আপনি এমন একটি সিগন্যাল হ্যান্ডলারও লিখতে পারেন যা এটি করে, এই লিঙ্কটি দেখুন


2
সিগন্যাল হ্যান্ডলার সমাধানে আপনার লিঙ্কটি মারা গেছে - এই কারণেই উত্তরগুলি অন্য সংস্থানগুলির সাথে লিঙ্ক করা উচিত নয় ...
জোছ

1
আপনার সম্ভবত "-x gdb কে" এক্সিকিউট করতে বলে "-x gdb কে প্রস্থান করতে বলে" এর অর্থ সম্ভবত
josch

19

দু'বছর পরে এখানে আসার জন্য দুঃখিত ... অন্য কিছুর সন্ধান করতে গিয়ে হোঁচট খেয়েছে। সম্পূর্ণতার জন্য এটি যুক্ত করা হচ্ছে।

1) যদিও আমি মনে করি গ্রহণযোগ্য উত্তরটি দুর্দান্ত, তবে এটির জন্য জিডিবি দরকার। আমি যে পদ্ধতিটির সাথে পরিচিত, সেগুলি libegFault.so ব্যবহার করে।

আপনি যদি আপনার অ্যাপ্লিকেশনটি চালিয়ে যান

LD_PRELOAD = ... পাথ-টু ... / libSegFault.so মায়াপ

আপনি ব্যাকট্র্যাস, বোঝা libs, ইত্যাদি সঙ্গে একটি প্রতিবেদন পেতে হবে

২) একটি মোড়ক স্ক্রিপ্টও catchsegvপাওয়া যায় যা addr2lineফাইলের নাম + লাইন নম্বরে ঠিকানা অনুবাদ করার চেষ্টা করবে ।

এগুলি মূল ফাইল বা জিডিবি-র তুলনায় অনেক হালকা সমাধান (উদাহরণস্বরূপ এম্বেড হওয়া সিস্টেমগুলির জন্য ভাল)


আসলে, LD_PRELOAD=libSegFault.soঠিক আছে যদি এটি ডিএল পথে থাকে।
ফার্নান্দো সিলভিরা

1
পছন্দ করুন উত্তরটি এইভাবে লেখা পাঠককে ইঙ্গিত দেয় যে তাদের সেই পথটি কী তা পরীক্ষা করা উচিত।
১৩ ই

6

আপনার প্রত্যেকের বন্ধু জিডিবি দরকার

gdb <program> [core file]

আপনি আপনার কোরফাইলটি লোড করার পরে, 'ব্যাকট্র্যাস' (বিটি-র সংক্ষেপে সংক্ষেপে বলা যেতে পারে) কমান্ডটি আপনাকে বর্তমান কল স্ট্যাক দেবে। আপনি যদি জিডিবির ভিতরে থেকে আপনার প্রোগ্রামটি চালনা করেন তবে আপনি নির্বিচারে ব্রেকপয়েন্টগুলি সেট করতে পারেন এবং মেমরির সামগ্রীগুলি পরীক্ষা করতে পারেন ইত্যাদি can


এটি কি কেবল ব্যাকট্রেস মুদ্রণ এবং প্রস্থান করার উপায় আছে?
নীল

5

catchsegv

এটি অন্য উত্তরে উল্লেখ করা হয়েছিল (তবে কোনওভাবেই দৃষ্টি নিবদ্ধ করা হয়নি)। এটি glibc প্রকল্পের সাথে বান্ডিল করা একটি সহজ সরঞ্জাম। এটি কোনও ব্যাকট্রিজ (এবং অন্যান্য দরকারী ডিবাগ তথ্য) সরবরাহ করবে কেবলমাত্র যদি কোনও প্রোগ্রাম সত্যিকার অর্থে সেগফল্ট করে।

একটি ভাল লেখার আপ এখানে বিদ্যমান ।

আপনি যথাযথ দেখতে দেখতে এটি নিজের স্ক্রিপ্টগুলিতে অন্তর্ভুক্ত করতে পারেন।


3

উবুন্টু (প্রকল্প হিসাবে) এটি করার জন্য অ্যাপপোর্ট ব্যবহার করে। তারা এটি কীভাবে করেছে তা আপনি দেখতে পারেন।

https://wiki.ubuntu.com/Apport


2
+1: অ্যাপোর্টে এমন কিছু দরকারী ব্যবস্থার উল্লেখ রয়েছে যার সাথে আমি পরিচিত ছিলাম না/proc/sys/kernel/core_pattern
রবএম

2

কাইল ব্র্যান্ডের স্ক্রিপ্টের কিছুটা পরিবর্তিত রূপ এখানে। এটি নিম্নলিখিত উপায়ে উন্নত করা হয়েছে:

  • স্ট্যাক ট্রেস দীর্ঘ হলে ম্যানুয়াল ইন্টারঅ্যাকশন প্রয়োজন হবে না
  • কিছু করডাম্প নামের প্যাটার্ন কোর দিয়ে সংরক্ষণ করা হয়,
  • জিডিবি-র জন্য একটি স্পষ্ট কমান্ড ফাইলের প্রয়োজন নেই (এটি একটি অস্থায়ী তৈরি করবে)
  • পটভূমি কাজের জন্য অপেক্ষা করুন

লিপি:

#!/bin/bash
gdbcommandfile=$(tempfile)
usepid=$(cat /proc/sys/kernel/core_uses_pid)
printf "set pagination off\nbacktrace\nquit\n" > $gdbcommandfile
ulimit -c unlimited
"$@"&
pid=$!
wait $!
if [[ $? -eq 139 ]]; then
    if [[ $usepid == 1 ]]; then 
        gdb -q $1 core.$pid -x $gdbcommandfile
    else
        gdb -q $1 core -x $gdbcommandfile
    fi
fi
rm $gdbcommandfile

1
এই জাতীয় সহজ কমান্ডগুলির একটি শৃঙ্খলার জন্য, আমি কেবল -exপরিবর্তে ব্যবহার করব । gdb ... -ex 'set pagination off' -ex backtrace -ex quit
জোশ স্টোন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.