"বাস ত্রুটি" বার্তাটি কী বোঝায় এবং এটি কীভাবে সেগফল্ট থেকে পৃথক হয়?
"বাস ত্রুটি" বার্তাটি কী বোঝায় এবং এটি কীভাবে সেগফল্ট থেকে পৃথক হয়?
উত্তর:
আজকাল x86 এ বাস ত্রুটি বিরল এবং যখন প্রসেসর এমনকি অনুরোধ করা মেমরি অ্যাক্সেস চেষ্টা করতে না পারে তখনই ঘটে:
মেমরি অ্যাক্সেস করার সময় বিভাজন ত্রুটি ঘটে যা যা আপনার প্রক্রিয়াভুক্ত নয়, সেগুলি খুব সাধারণ এবং সাধারণত এর ফলাফল:
পিএস: আরও সুনির্দিষ্টভাবে বলতে গেলে এটি পয়েন্টারটি নিজেই চালিত করে না যা সমস্যার কারণ হয়ে দাঁড়ায়, এটি মেমরিটিকে নির্দেশ করে যা এটি (ডিসিফারেন্সিং) নির্দেশ করে।
/var/cache
কেবল সম্পূর্ণ জিজ্ঞাসুবন্টু.com
static_cast
একটি void *
প্যারামিটার সম্পাদনা করে যা একটি কলব্যাক সঞ্চয় করে (একটি বৈশিষ্ট্যটি বস্তুর দিকে নির্দেশ করে এবং অন্যটি পদ্ধতিতে)। তারপরে কলব্যাক বলা হয়। তবে, যা পাস করা void *
হয়েছিল তা সম্পূর্ণ আলাদা কিছু ছিল এবং এইভাবে পদ্ধতি কলটি বাসের ত্রুটির কারণ হয়েছিল।
একটি সেগফল্ট মেমরি অ্যাক্সেস করছে যা আপনাকে অ্যাক্সেস করার অনুমতি নেই। এটি কেবল পঠনযোগ্য, আপনার অনুমতি নেই ইত্যাদি ইত্যাদি ...
একটি বাস ত্রুটি মেমরি অ্যাক্সেস করার চেষ্টা করছে যা সম্ভবত সেখানে থাকতে পারে না। আপনি এমন কোনও ঠিকানা ব্যবহার করেছেন যা সিস্টেমের কাছে অর্থহীন নয় বা সেই অপারেশনের জন্য ভুল ধরণের ঠিকানা।
mmap
ন্যূনতম পসিক্স 7 উদাহরণ
"বাস ত্রুটি" ঘটে যখন কার্নেল SIGBUS
কোনও প্রক্রিয়াতে প্রেরণ করে।
একটি ন্যূনতম উদাহরণ যা এটি উত্পাদন করে কারণ ftruncate
ভুলে গিয়েছিল:
#include <fcntl.h> /* O_ constants */
#include <unistd.h> /* ftruncate */
#include <sys/mman.h> /* mmap */
int main() {
int fd;
int *map;
int size = sizeof(int);
char *name = "/a";
shm_unlink(name);
fd = shm_open(name, O_RDWR | O_CREAT, (mode_t)0600);
/* THIS is the cause of the problem. */
/*ftruncate(fd, size);*/
map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
/* This is what generates the SIGBUS. */
*map = 0;
}
সাথে চালান:
gcc -std=c99 main.c -lrt
./a.out
উবুন্টু 14.04 এ পরীক্ষিত।
পসিক্স বর্ণনা SIGBUS
করে:
মেমরি অবজেক্টের একটি অপরিজ্ঞাত অংশে অ্যাক্সেস।
Mmap বৈশিষ্ট যে বলেন:
অ্যাড্রেস রেঞ্জের মধ্যে রেফারেন্সগুলি Pa থেকে শুরু হবে এবং অবজেক্টের শেষের পরে পুরো পৃষ্ঠায় লেন বাইটের জন্য চালিয়ে যাওয়ার ফলে একটি সাইনবাস সিগন্যাল সরবরাহ করা হবে।
এবং shm_open
বলে যে এটি 0 আকারের অবজেক্ট তৈরি করে:
ভাগ করা মেমরি অবজেক্টটির আকার শূন্য has
সুতরাং *map = 0
আমরা বরাদ্দ করা অবজেক্টের শেষটি ছুঁয়ে যাচ্ছি।
স্বাক্ষরবিহীন স্ট্যাক মেমরি এআরএমভি 8 আর্চ 64 এ অ্যাক্সেস করে
এটি উল্লেখ করা হয়েছিল: একটি বাস ত্রুটি কি? স্পার্কের জন্য, তবে এখানে আমি আরও পুনরুত্পাদনযোগ্য উদাহরণ সরবরাহ করব।
আপনার যা দরকার তা হ'ল একটি নিরস্তর পরিবেশক arch৪ প্রোগ্রাম:
.global _start
_start:
asm_main_after_prologue:
/* misalign the stack out of 16-bit boundary */
add sp, sp, #-4
/* access the stack */
ldr w0, [sp]
/* exit syscall in case SIGBUS does not happen */
mov x0, 0
mov x8, 93
svc 0
সেই প্রোগ্রামটি তখন একটি থান্ডারএক্স 2 সার্ভার মেশিনে উবুন্টু 18.04 আর্চ 64, লিনাক্স কার্নেল 4.15.0 এ সিগবস উত্থাপন করে ।
দুর্ভাগ্যক্রমে, আমি এটিকে QEMU v4.0.0 ব্যবহারকারী মোডে পুনরুত্পাদন করতে পারি না, কেন তা আমি নিশ্চিত নই।
ফল্টটি fieldsচ্ছিক SCTLR_ELx.SA
এবং SCTLR_EL1.SA0
ক্ষেত্রগুলি দ্বারা নিয়ন্ত্রিত বলে মনে হয় , আমি এখানে সম্পর্কিত ডকসগুলি আরও কিছুটা সংক্ষেপে জানিয়েছি ।
আমি বিশ্বাস করি যখন কোনও অ্যাপ্লিকেশন ডেটা বাসে ডেটা বিভ্রান্তি প্রদর্শন করে তখন কার্নেল সিগবূসকে উত্থাপন করে। আমি মনে করি যেহেতু বেশিরভাগ প্রসেসরের জন্য আধুনিক সংকলকগণ প্রোগ্রামারগুলির জন্য প্যাড / তথ্য প্রান্তিককরণ করছেন, ইয়ারের প্রান্তিককরণের সমস্যাগুলি (কমপক্ষে) প্রশমিত করা হয়েছে, এবং তাই আজকের দিনে সিগাবাস খুব বেশি দেখা যায় না (এএফআইকে)।
থেকে: এখানে
কোনও কারণে যখন কোনও পৃষ্ঠা পৃষ্ঠাতে প্রবেশ করা যায় না তখন আপনি সিগবাসও পেতে পারেন।
mmap
আকারের চেয়ে বড় কোনও ফাইলের চেষ্টা করেন/dev/shm
ওএস এক্স-তে সি প্রোগ্রামিং করার সময় একটি বাস ত্রুটির একটি নির্দিষ্ট উদাহরণ:
#include <string.h>
#include <stdio.h>
int main(void)
{
char buffer[120];
fgets(buffer, sizeof buffer, stdin);
strcat("foo", buffer);
return 0;
}
আপনি যদি মনে করেন না ডক্স strcat
প্রথম যুক্তিটি পরিবর্তন করে প্রথম যুক্তিতে দ্বিতীয় যুক্তিকে সংযোজন করে (আর্গুমেন্টগুলি ফ্লিপ করুন এবং এটি সূক্ষ্মভাবে কাজ করে)। লিনাক্সে এটি একটি সেগমেন্টেশন ত্রুটি দেয় (যেমনটি প্রত্যাশিত) তবে ওএস এক্সে এটি একটি বাস ত্রুটি দেয়। কেন? আমি সত্যিই জানি না।
"foo"
কেবল মেমরির পঠনযোগ্য বিভাগে এটি সঞ্চয় করা আছে, তাই এটিতে লেখা অসম্ভব। এটি স্ট্যাক ওভারফ্লো সুরক্ষা হবে না, কেবল মেমরি লেখার সুরক্ষা (এটি যদি আপনার প্রোগ্রাম নিজেই আবার লিখতে পারে তবে এটি একটি সুরক্ষা গর্ত)।
বাসের ত্রুটির একটি ক্লাসিক উদাহরণ নির্দিষ্ট আর্কিটেকচারগুলিতে যেমন: স্পার্ক (কমপক্ষে কিছু এসপিআরসি, সম্ভবত এটি পরিবর্তিত হয়েছে) হয়, যখন আপনি কোনও ভুল-প্রান্তিকৃত অ্যাক্সেস করেন। এই ক্ষেত্রে:
unsigned char data[6];
(unsigned int *) (data + 2) = 0xdeadf00d;
এই স্নিপেটটি 32-বিট পূর্ণসংখ্যার মানটি 0xdeadf00d
এমন ঠিকানায় লেখার চেষ্টা করে যা সম্ভবত (সঠিকভাবে প্রান্তিক নয়), এবং আর্কিটেকচারের ক্ষেত্রে "ত্রুটিযুক্ত" বাসে একটি ত্রুটি তৈরি করবে। ইন্টেল এক্স 86 উপায় দ্বারা, হয় না যেমন একটি স্থাপত্য, এটা অ্যাক্সেস (যদিও এটা আরো ধীরে ধীরে চালানো) সম্ভব হবে।
এটি আপনার ওএস, সিপিইউ, সংকলক এবং সম্ভবত অন্যান্য কারণের উপর নির্ভর করে।
সাধারণভাবে এর অর্থ সিপিইউ বাস কোনও কমান্ড শেষ করতে পারেনি, বা দ্বন্দ্বের মুখোমুখি হয়েছে, তবে এর অর্থ পরিবেশ এবং কোড চালিত হওয়ার উপর নির্ভর করে সামগ্রিক পরিসরের পরিমাণ থাকতে পারে।
-Adam
এর অর্থ সাধারণত অ-অ্যালাইন্টেড অ্যাক্সেস।
শারীরিকভাবে উপস্থিত না থাকা মেমোরির অ্যাক্সেসের একটি প্রচেষ্টাও একটি বাস ত্রুটি দিতে পারে তবে আপনি এটি দেখতে পাবেন না যদি আপনি কোনও এমএমইউ এবং একটি বাগি নেই এমন একটি প্রসেসর ব্যবহার করছেন, কারণ আপনার কোনও অকার্যকর হবে না আপনার প্রক্রিয়া ঠিকানা স্থানে মেমরি মেশানো।
scanf
)। এর অর্থ কি ওএস এক্স মাভারিক্স বগি? নন-বগি ওএসের আচরণটি কী হত?
ম্যাক ওএস এক্সে আমার বাসের ত্রুটির কারণ হ'ল আমি স্ট্যাকটিতে প্রায় 1 এমবি বরাদ্দ করার চেষ্টা করেছি। এটি একটি থ্রেডে ভাল কাজ করেছে, তবে ওপেনএমপি ব্যবহারের সময় এই ড্রাইভগুলি বাসের ত্রুটিতে চলেছে, কারণ ম্যাক ওএস এক্সের অ-প্রধান থ্রেডগুলির জন্য খুব সীমিত স্ট্যাক আকার রয়েছে ।
আমি উপরের সমস্ত উত্তর সাথে একমত। এখানে বিএস ত্রুটি সম্পর্কিত আমার 2 সেন্ট রয়েছে:
প্রোগ্রামের কোডের মধ্যে থাকা নির্দেশাবলী থেকে কোনও বিএস ত্রুটি উদয় হওয়ার দরকার নেই। এটি ঘটতে পারে যখন আপনি বাইনারি চালাচ্ছেন এবং এক্সিকিউশন চলাকালীন সময়ে বাইনারিটি সংশোধন করা হয় (বিল্ড দ্বারা মুছে ফেলা বা মোছা ইত্যাদি)।
এটি ক্ষেত্রে কিনা তা যাচাই করা হচ্ছে:
এটি কারণ কিনা তা যাচাই করার একটি সহজ উপায় হ'ল একই বাইনারিটির চলমান দৃষ্টান্তগুলি চালু করে একটি বিল্ড চালানো। SIGBUS
বিল্ডিং শেষ হয়ে যাওয়ার পরে এবং বাইনারি প্রতিস্থাপনের (উভয় দৃষ্টান্তই বর্তমানে চলছে এমন একটি) দু'টি চলমান দৃষ্টান্তই ত্রুটির সাথে ক্রাশ হবে both
অন্তর্নিহিত কারণ: এটি কারণ মেমরি পৃষ্ঠাগুলি অদলবদল করে এবং কিছু ক্ষেত্রে বাইনারি পুরোপুরি মেমরিতে লোড না হতে পারে এবং ওএস একই বাইনারি থেকে পরবর্তী পৃষ্ঠাটি আনার চেষ্টা করলে এই ক্র্যাশগুলি ঘটতে পারে তবে বাইনারিটি শেষ হওয়ার পর থেকে পরিবর্তিত হয়েছে এটি পড়ুন।
উপরে blxtd জবাব দিয়েছিল তা যুক্ত করতে, আপনার প্রক্রিয়া কোনও নির্দিষ্ট 'ভেরিয়েবল' এর মেমোরি অ্যাক্সেস করতে না পারলে বাস ত্রুটিগুলিও ঘটে ।
for (j = 0; i < n; j++) {
for (i =0; i < m; i++) {
a[n+1][j] += a[i][j];
}
}
লক্ষ্য করুন ' অসাবধানী এর ব্যবহার দেখে ' আমি 'পরিবর্তনশীল মধ্যে ' লুপ জন্য 'প্রথম? এই ক্ষেত্রে বাসের ত্রুটি ঘটছে।
আমি কেবল শক্ত উপায়টি খুঁজে পেয়েছি যে কোনও এআরএমভি 7 প্রসেসরে আপনি এমন কিছু কোড লিখতে পারেন যা আপনাকে অপরিশোধিত করার সময় একটি সেগমেন্টেশন ত্রুটি দেয় তবে -O2 (আরও অনুকূলিতকরণ) সংকলন করার সময় এটি আপনাকে একটি বাস ত্রুটি দেয়।
আমি উবুন্টু bit৪ বিট থেকে জিসিসি এআরএম জেনুয়েবিহফ ক্রস সংকলক ব্যবহার করছি।
একটি সাধারণ বাফার ওভারফ্লো যা বাসের ত্রুটির ফলস্বরূপ,
{
char buf[255];
sprintf(buf,"%s:%s\n", ifname, message);
}
এখানে যদি ডাবল উদ্ধৃতিতে ("") স্ট্রিংয়ের আকার বুফ আকারের চেয়ে বেশি হয় তবে এটি বাসের ত্রুটি দেয়।