विषय पर बढ़ें

अंतिम अद्यतन:2026-10-12

AddressSanitizer memory detection

C और C++ बहुत unsafe और गलतियों के प्रति संवेदनशील programming languages हैं, Address Sanitizer, Google द्वारा विकसित एक tool है, जो memory access errors, जैसे use-after-free और memory leaks detect करने के लिए है। यह GCC version >= 4.8 में integrate हो चुका है, और C तथा C++ code के लिए उपयोग किया जा सकता है। Address Sanitizer memory allocation को track करने के लिए runtime instrumentation उपयोग करता है, इसका मतलब है कि आपको इसकी क्षमताओं का पूरा लाभ लेने के लिए अपने code को AddressSanitizer के साथ build करना होगा।

इस लेख में ऊपर दिए 8 परिदृश्यों के आधार पर memory detection tool AddressSanitizer का परिचय दिया जाएगा।

1. Use after free

नीचे दिए code का उदाहरण लेते हैं। सबसे पहले, new keyword से एक integer के लिए memory space allocate की गई, और उसका address pointer ptr को assign किया गया। फिर, delete keyword से यह memory release कर दी गई। लेकिन, release के बाद भी program pointer ptr के ज़रिए release हो चुकी memory को access करने की कोशिश करता है, और उस memory location पर value 10 assign करता है, यही use-after-free error है।

#include <iostream>

int main() {
  int* ptr = new int;
  delete ptr;
  *ptr = 10;  // Use after free
  return 0;
}

Compile करते समय निम्न option जोड़ें।

-fsanitize=address

बनी bin फ़ाइल run करने पर, निम्न परिणाम मिलता है।

heap use after free

2. heap buffer overflow

सबसे पहले, new keyword से heap पर दो integers वाला एक array allocate किया गया, और array का starting address pointer arr को assign किया गया। फिर, program value 10 को array की तीसरी position (index 2) पर store करने की कोशिश करता है, जो array की valid range से बाहर है, जिससे heap buffer overflow error होता है।

#include <iostream>

int main() {
  int* arr = new int[2];
  arr[2] = 10;  // Heap buffer overflow
  delete[] arr;
  return 0;
}

ऊपर वाले उपयोग जैसा ही:

g++-13 heap_buffer_overflow.cc  -Wall -g -fsanitize=address 

फिर:

./a.out

नीचे detection परिणाम मिलता है।

heap_buffer_overflow

3. stack buffer overflow

vulnerableFunction function में, 8 characters वाला एक character array buffer define किया गया है। फिर, std::cin से standard input का data buffer में पढ़ा जाता है, पर input के size की कोई सीमा नहीं है। अगर input के characters की संख्या buffer के size से बढ़ जाती है, तो stack buffer overflow error होगा।

void vulnerableFunction() {
  char buffer[8];
  std::cin >> buffer;  // Stack buffer overflow
  std::cout << "You entered: " << buffer << std::endl;
}

उपयोग ऊपर जैसा ही।

stack_buffer_overflow

4. global buffer overflow

Global buffer (buffer array) program के global scope में define है, और input size की पर्याप्त सीमा नहीं है। अगर input के characters की संख्या buffer के size से बढ़ जाए, तो global buffer overflow error होगा। Stack buffer overflow के समान, global buffer overflow से program की instability और security समस्याएँ हो सकती हैं।

#include <iostream>

char buffer[8];

int main() {
    std::cin >> buffer; // 全局缓冲区溢出错误
    std::cout << "You entered: " << buffer << std::endl;
    return 0;
}

उपयोग ऊपर जैसा ही, इससे मिलता है:

global_buffer_overflow

5. use after return

Function f में, local variable i का address return किया जाता है, लेकिन main function में, return किए गए pointer से destroy हो चुके local variable को access करने की कोशिश होती है। ऐसा परिदृश्य आने पर, bin फ़ाइल की जांच की जा सकती है, ASAN_OPTIONS=detect_stack_use_after_return=1 सेट करके।

g++-13 stack_use_after_return.cc -Wall -g -fsanitize=address
ASAN_OPTIONS=detect_stack_use_after_return=1 ./a.out

Code:

#include <iostream>

int *f() {
  int i = 42;
  int *p = &i;
  return p;
}

int main() { return *f(); }

हमें यह मिलेगा:

stack_use_after_return

6. use after scope

Local variable x का address pointer p को assign किया गया, लेकिन उस inner scope से बाहर निकलने के बाद, pointer p से range से बाहर हो चुके local variable x को access करने की कोशिश की जाती है, जिससे out-of-scope use error होता है। यह भी undefined behavior है।

#include <iostream>
int main() {
  int* p = 0;
  {
    int x = 0;
    p = &x;
  }
  *p = 5;
  return 0;
}

Compilation और run:

g++-13 stack_use_after_scope.cc -Wall -g -fsanitize=address
ASAN_OPTIONS=detect_stack_use_after_scope=0  ./a.out 

परीक्षण में clang++ कर पाता है, g++ detect नहीं कर पाता।

stack_use_after_scope

7. Initialization order bugs

दो अलग source files में, global variable a का initialization है, पर initialization का order निश्चित नहीं है। init_order_b.cc फ़ाइल में, variable a की value उपयोग करने की कोशिश होती है, लेकिन initialization order के अंतर के कारण undefined behavior हो सकता है।

Code इस प्रकार है:

// init_order_a.cc
int duplicate(int n) { return n * 2; }
auto a = duplicate(2);

// init_order_b.cc
#include <iostream>

extern int a;
auto b = a;  

int main() {
  std::cout << b << std::endl;
  return 0;
}

जब हम ऐसा code लिखते हैं, तो उसका परिणाम अनिश्चित है, हो सकता है 4 और हो सकता है 0, initialization के order पर निर्भर करता है।

उदाहरण के लिए:

clang++ init_order_a.cc init_order_b.cc  -Wall -g -fsanitize=address

ऐसे आउटपुट 4 आता है, जबकि पहले b compile करके, बाद में a compile करने पर 0 मिलता है।

clang++ init_order_b.cc init_order_a.cc  -Wall -g -fsanitize=address

ऐसी समस्या आने पर, हम AddressSanitizer से initialization order की जांच कर सकते हैं।

ASAN_OPTIONS=check_initialization_order=true ./a.out 

init_order

8. memory leak

new keyword से एक integer की memory dynamically allocate की गई, लेकिन program समाप्त होने से पहले delete keyword से इस memory को release नहीं किया गया, जिससे memory leak हुई।

#include <iostream>

int main() {
  int* ptr = new int;
  // Missing delete ptr; // Memory leak
  return 0;
}

ASAN_OPTIONS=detect_leaks=1 सेट करें।

ASAN_OPTIONS=detect_leaks=1 ./a.out

memory_leak

संबंधित विषय

टिप्पणियाँ