ন্যূনতম চলমান উদাহরণ
ব্র্যাক () সিস্টেম কল কী করে?
কর্নেলকে জিজ্ঞাসা করে যে আপনাকে হিপ বলা মেমরির একটি স্বল্প অংশ পড়তে এবং লিখতে দেয়।
আপনি যদি না জিজ্ঞাসা করেন তবে এটি আপনাকে সেগফল্ট করতে পারে।
ছাড়া brk
:
#define _GNU_SOURCE
#include <unistd.h>
int main(void) {
/* Get the first address beyond the end of the heap. */
void *b = sbrk(0);
int *p = (int *)b;
/* May segfault because it is outside of the heap. */
*p = 1;
return 0;
}
সহ brk
:
#define _GNU_SOURCE
#include <assert.h>
#include <unistd.h>
int main(void) {
void *b = sbrk(0);
int *p = (int *)b;
/* Move it 2 ints forward */
brk(p + 2);
/* Use the ints. */
*p = 1;
*(p + 1) = 2;
assert(*p == 1);
assert(*(p + 1) == 2);
/* Deallocate back. */
brk(b);
return 0;
}
গিটহাব উজানের দিকে ।
brk
উপরেরটি কোনও নতুন পৃষ্ঠাতে আঘাত না করে এমনকি সেগফ্লটকে নাও মেরে ফেলতে পারে, সুতরাং এখানে আরও আক্রমণাত্মক সংস্করণ দেওয়া হয়েছে যা ১M এমআইবি বরাদ্দ করে এবং সেগফোল্ট ছাড়াই খুব সম্ভবত brk
:
#define _GNU_SOURCE
#include <assert.h>
#include <unistd.h>
int main(void) {
void *b;
char *p, *end;
b = sbrk(0);
p = (char *)b;
end = p + 0x1000000;
brk(end);
while (p < end) {
*(p++) = 1;
}
brk(b);
return 0;
}
উবুন্টু 18.04 এ পরীক্ষিত।
ভার্চুয়াল ঠিকানার স্থানের দৃশ্যায়ন
আগে brk
:
+------+ <-- Heap Start == Heap End
পরে brk(p + 2)
:
+------+ <-- Heap Start + 2 * sizof(int) == Heap End
| |
| You can now write your ints
| in this memory area.
| |
+------+ <-- Heap Start
পরে brk(b)
:
+------+ <-- Heap Start == Heap End
ঠিকানার জায়গাগুলি আরও ভালভাবে বুঝতে, আপনার নিজের পেজিংয়ের সাথে পরিচিত হওয়া উচিত: x86 পেজিং কীভাবে কাজ করে? ।
কেন আমরা প্রয়োজন উভয় না brk
এবং sbrk
?
brk
অবশ্যই sbrk
+ অফসেট গণনা দ্বারা বাস্তবায়িত হতে পারে , উভয়ই কেবল সুবিধার জন্য বিদ্যমান।
ব্যাকএন্ডে, লিনাক্স কার্নেল v5.0 এর একটি একক সিস্টেম কল রয়েছে brk
যা উভয়ই প্রয়োগ করতে ব্যবহৃত হয়: https://github.com/torvalds/linux/blob/v5.0/arch/x86/entry/syscalls/syscall_64 উভয়ই প্রয়োগ করতে । tbl # L23
12 common brk __x64_sys_brk
brk
পসিক্স কি ?
brk
পসিক্স হিসাবে ব্যবহৃত হত, তবে এটি পসিক্স 2001-এ সরিয়ে ফেলা হয়েছিল, সুতরাং _GNU_SOURCE
গ্লিবসি মোড়কে অ্যাক্সেসের প্রয়োজন ।
অপসারণ সম্ভবত প্রবর্তনের কারণে ঘটে mmap
যা একটি সুপারসেট যা একাধিক পরিসর বরাদ্দ করতে এবং আরও বেশি বরাদ্দকরণের বিকল্প দেয়।
আমি মনে করি যে আজকাল আপনার brk
পরিবর্তে malloc
বা আপনার ব্যবহার করা উচিত এমন কোনও বৈধ মামলা নেই mmap
।
brk
বনাম malloc
brk
বাস্তবায়ন এক পুরানো সম্ভাবনা malloc
।
mmap
এটি আরও শক্তিশালী আরও শক্তিশালী প্রক্রিয়া যা সম্ভবত সমস্ত পসিক্স সিস্টেম বর্তমানে প্রয়োগ করতে ব্যবহার করে malloc
। এখানে একটি ন্যূনতম চলমানযোগ্য mmap
মেমরি বরাদ্দ উদাহরণ ।
আমি মিক্স brk
এবং malloc করতে পারেন ?
যদি আপনার সাথে malloc
এটি প্রয়োগ করা হয় brk
, তবে কীভাবে এটি সম্ভবত জিনিসগুলিকে উড়িয়ে দিতে পারে না সে সম্পর্কে আমার কোনও ধারণা নেই, যেহেতু brk
কেবলমাত্র একক পরিসরে মেমরি পরিচালনা করে।
তবে গ্লিবসি ডক্সে আমি এটি সম্পর্কে কিছুই খুঁজে পাইনি, যেমন:
জিনিসগুলি সম্ভবত সেখানে কাজ করবে বলে আমি মনে করি যেহেতু mmap
সম্ভবত এটি ব্যবহার করা হয়েছে malloc
।
আরো দেখুন:
অধিক তথ্য
অভ্যন্তরীণভাবে, কার্নেল সিদ্ধান্ত নিয়েছে যে প্রক্রিয়াটিতে এত বেশি মেমরি থাকতে পারে এবং সেই ব্যবহারের জন্য এয়ারমার্ক মেমরি পৃষ্ঠা রয়েছে ।
এটি ব্যাখ্যা করে যে স্ট্যাকটি কীভাবে স্তূপের সাথে তুলনা করে: x86 অ্যাসেমব্লিতে রেজিস্টারগুলিতে ব্যবহৃত পুশ / পপ নির্দেশাবলীর কাজ কী?