Search…

Phát Hiện Memory Leak với VLD

06/09/20205 min read
Memory Leak – rò rỉ bộ nhớ xảy ra khi ta cấp phát một vùng nhớ và không thu hồi lại chúng sau khi sử dụng. Để tránh việc này xảy ra, theo lý thuyết là bất kể khi nào ta gọi toán tử new thì ngay sau đó ta cần gọi toán tử delete (tương ứng với cặp đôi malloc(...) - free(...)). Bài viết hướng dẫn bạn đọc sử dụng thư viện VLD để phát hiện memory leak.

Với lượng dữ liệu trong bộ nhớ lớn, xét xem đã hủy các vùng nhớ sau khi sử dụng mà không dùng bất kì một công cụ hỗ trợ nào, gần như là một việc tốn rất nhiều thời gian và không hiệu quả do sơ sót thủ công.

Chính vì vậy thư viện hỗ trợ cho việc phát hiện Memory Leak ra đời Visual Leak Detector.

Visual Leak Detector là gì?

Visual Leak Detector (VLD) là một thư viện mã nguồn mở hoàn toàn miễn phí giúp xác định memory leak trong chương trình. VLD chỉ tương thích với Visual C++.

Tùy theo phiên bản Visual Studio mà tải phiên bản VLD phù hợp. Trong trường hợp bài viết đang sử dụng VLD v2.4rc2 cùng Visual Studio 2013 Community.

Cài đặt và sử dụng VLD

Cài đặt VLD

Sau khi tải xuống hoàn tất, tiến hành cài đặt VLD vào máy tính. Để tiện lợi trong quá trình sử dụng, có thể giữ nguyên phần cấu hình cài đặt mặc định.

Nếu quá trình cài đặt thành công, trong folder Program Files sẽ có thêm folder Visual Leak Detector với cấu trúc như sau:

VLD - Visual Studio Community.

Sử dụng VLD

Muốn sử dụng VLD, thêm include sau vào tất cả các file .cpp

#include <vld.h>

Để minh họa cho việc sử dụng VLD, đầu tiên cần giả lập môi trường ứng dụng đang có memory leak bằng cách cấp phát một vùng nhớ ngẫu nhiên và cố tình không gọi lệnh hủy.

#include <string.h>

int main()
{
    char* p = new char[1024];
    char* str = strdup("Hello Stdio!");

return 0; }

Nếu không khai báo sử dụng VLD, đoạn chương trình sẽ kết thúc mà không có bất cứ thông báo gì đặc biệt.

Tiếp theo, khai báo sử dụng thư viện VLD như trong đoạn mã dưới đây:

#include <string.h>
#include <vld.h>

int main()
{
    char* p = new char[1024];
    char* str = strdup("Hello Stdio!");

return 0; }

Sau khi chương trình kết thúc, VLD sẽ lần lượt rà soát lại tất cả các vùng nhớ đã cấp phát mà chưa gọi lệnh hủy. Điểm đặc biệt nhất là VLD thông báo cho 1 cách rất chi tiết về vùng nhớ bị leak: kích thước, dữ liệu, call stack, ... như trong ví dụ dưới đây:

Visual Leak Detector Version 2.4RC2 installed.
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 1 at 0x0044DC58: 1024 bytes ----------
  Leak Hash: 0xABCDB444, Count: 1, Total 1024 bytes
  Call Stack (TID 18000):
    0x0F87C260 (File and line number not available): MSVCR120D.dll!operator new
    c:\users\huy.vuquang\documents\visual studio 2013\projects\stdio_vld_demo\main.cpp (6): STDIO_VLD_Demo.exe!main + 0xA bytes
    f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c (626): STDIO_VLD_Demo.exe!__tmainCRTStartup + 0x19 bytes
    f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c (466): STDIO_VLD_Demo.exe!mainCRTStartup
    0x7648919F (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0xE bytes
    0x77BD0BBB (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x84 bytes
    0x77BD0B91 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x5A bytes
  Data:
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........


---------- Block 2 at 0x0044E088: 14 bytes ----------
  Leak Hash: 0x9E7F558B, Count: 1, Total 14 bytes
  Call Stack (TID 18000):
    0x0F7D80F0 (File and line number not available): MSVCR120D.dll!strdup
    c:\users\huy.vuquang\documents\visual studio 2013\projects\stdio_vld_demo\main.cpp (7): STDIO_VLD_Demo.exe!main + 0xD bytes
    f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c (626): STDIO_VLD_Demo.exe!__tmainCRTStartup + 0x19 bytes
    f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c (466): STDIO_VLD_Demo.exe!mainCRTStartup
    0x7648919F (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0xE bytes
    0x77BD0BBB (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x84 bytes
    0x77BD0B91 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x5A bytes
  Data:
    48 65 6C 6C    6F 20 53 74    64 69 6F 20    21 00           Hello.St dio.!...


Visual Leak Detector detected 2 memory leaks (1110 bytes).
Largest number used: 1110 bytes.
Total allocations: 1110 bytes.
Visual Leak Detector is now exiting.

Lúc này, công việc còn lại dành cho lập trình viên là khảo sát các dòng code và ra các quyết định thu hồi phù hợp.

#include <string.h>
#include <vld.h>

int main()
{
    char* p = new char[1024];
    char* str = _strdup("Hello Stdio !");

    delete[] p;
    delete[] str;

return 0; }

Nếu VLD thông báo như dưới đây, thì có thể chắc chắn là ứng dụng không còn memory leak nữa.

Visual Leak Detector Version 2.4RC2 installed.
No memory leaks detected.
Visual Leak Detector is now exiting.
IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024