Lệnh nm trong linux với các ví dụ dễ hiểu

Lệnh nm trong Linux là một công cụ mạnh mẽ giúp bạn xem danh sách các biểu tượng (symbols) từ các file object, thư viện hoặc file thực thi. Nó hiển thị tên, giá trị và kiểu của các biểu tượng, giúp ích cho việc gỡ lỗi và hiểu cấu trúc chương trình. Sử dụng nm, bạn có thể dễ dàng xác định các hàm, biến toàn cục và các thành phần khác trong mã nguồn đã biên dịch. Đây là một công cụ không thể thiếu cho các nhà phát triển Linux.

Lệnh nm trong linux là gì?

Lệnh command nm in linux là một công cụ dòng lệnh mạnh mẽ, giúp bạn khám phá nội dung bên trong các file object, file thực thi và thư viện. Nó hiển thị danh sách các symbol (biến, hàm,...) được định nghĩa hoặc tham chiếu trong các file này, cùng với địa chỉ và loại của chúng. Sử dụng nm, bạn có thể hiểu rõ hơn về cấu trúc chương trình, gỡ lỗi, hoặc kiểm tra tính tương thích giữa các thư viện. Ví dụ, bạn có thể dùng nm để tìm xem một hàm cụ thể có tồn tại trong một thư viện hay không. Đây là một công cụ vô cùng hữu ích cho các lập trình viên và những người làm việc với hệ thống Linux.

Giới thiệu về Lệnh nm

Trong bước này, chúng ta sẽ khám phá lệnh nm trên Linux, dùng để hiển thị thông tin symbol của object file.

Lệnh nm là một công cụ hữu ích cho các developer và system administrator để hiểu cấu trúc bên trong của file thực thi.

Đầu tiên, hãy tạo một chương trình C đơn giản và biên dịch nó thành một file thực thi:

cd ~/project
nano hello.c

Thêm đoạn code sau vào file hello.c:

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

Bây giờ, hãy biên dịch chương trình:

gcc -o hello hello.c

Để xem thông tin symbol của file thực thi hello, chúng ta có thể sử dụng lệnh nm:

nm hello

Ví dụ về output:

0000000000001119 T main
                 U printf

Output cho thấy file thực thi hello có một symbol tên là main tại địa chỉ 0x0000000000001119.

Nó cũng tham chiếu đến symbol printf, có khả năng được cung cấp bởi thư viện chuẩn C.

Lệnh nm cung cấp nhiều option để tùy chỉnh output và lọc thông tin symbol, chúng ta sẽ khám phá chúng ở bước tiếp theo.

Hiển thị Thông tin Symbol của một Executable

Trong bước này, chúng ta sẽ khám phá các tùy chọn của lệnh nm để hiển thị thông tin symbol chi tiết hơn cho executable hello đã tạo ở bước trước.

Đầu tiên, hãy xem xét kỹ hơn đầu ra của lệnh nm cơ bản:

nm hello

Ví dụ đầu ra:

0000000000001119 T main
                 U printf

Đầu ra hiển thị tên symbol và địa chỉ của nó trong file executable. Chữ T cho biết main là một hàm global, và U nghĩa là printf là một symbol undefined, có thể được cung cấp bởi một thư viện bên ngoài.

Để có được thông tin chi tiết hơn, chúng ta có thể sử dụng các tùy chọn nm sau:

  • nm -A hello: Hiển thị tên file cùng với thông tin symbol.
  • nm -n hello: Sắp xếp đầu ra theo tên symbol thay vì địa chỉ.
  • nm -p hello: Hiển thị đầu ra ở định dạng post-processed dễ đọc hơn.
  • nm -C hello: Demangle tên symbol C++ để dễ đọc hơn.

Ví dụ đầu ra:

hello:0000000000001119 T main
hello:                 U printf

Bạn có thể kết hợp các tùy chọn này để tùy chỉnh đầu ra hơn nữa. Ví dụ:

nm -nC hello

Ví dụ đầu ra:

hello:                 U std::ostream::operator<<(char const*)
hello:0000000000001119 T main

Lệnh này hiển thị các symbol được sắp xếp theo tên, với tên symbol C++ được demangle để dễ đọc hơn.

Lệnh nm cung cấp rất nhiều thông tin về cấu trúc bên trong của các file executable, rất hữu ích cho các developer, system administrator và security researcher.

Lọc Thông Tin Symbol Sử Dụng Các Tùy Chọn nm

Trong bước này, chúng ta sẽ tìm hiểu cách dùng lệnh nm để lọc thông tin symbol cho file thực thi hello.

Đôi khi, kết quả của lệnh nm có thể rất nhiều, đặc biệt với các file thực thi lớn. Để tập trung vào các loại symbol cụ thể, ta có thể dùng các tùy chọn nm sau:

  • nm -D hello: Chỉ hiển thị các dynamic symbol (symbol được dùng bởi dynamic linker).
  • nm -T hello: Chỉ hiển thị các static (global) symbol.
  • nm -t <format> hello: Hiển thị địa chỉ symbol theo định dạng cụ thể (d cho decimal, x cho hexadecimal, o cho octal).
  • nm --defined-only hello: Chỉ hiển thị các symbol đã được định nghĩa (không phải external/undefined symbol).
  • nm --undefined-only hello: Chỉ hiển thị các symbol chưa được định nghĩa.

Ví dụ, để hiển thị các dynamic symbol ở định dạng hexadecimal:

nm -Dt hello

Kết quả ví dụ:

0000000000001119 T main
                 U printf

Để chỉ hiển thị các static (global) symbol:

nm -T hello

Kết quả ví dụ:

0000000000001119 T main

Bạn có thể kết hợp các tùy chọn này để tinh chỉnh kết quả hơn nữa. Ví dụ, để chỉ hiển thị các symbol đã định nghĩa ở định dạng dễ đọc hơn:

nm --defined-only -nC hello

Kết quả ví dụ:

hello:0000000000001119 T main

Lọc thông tin symbol đặc biệt hữu ích khi làm việc với các file thực thi lớn hoặc phức tạp. Nó cho phép bạn tập trung vào các symbol cụ thể mà bạn quan tâm.

Kết luận cho linux nm command

```html

Tóm lại, lệnh nm là một công cụ vô cùng hữu ích để khám phá cấu trúc bên trong của các file object và thư viện trong Linux. Nó giúp bạn hiểu rõ hơn về các symbol, địa chỉ và kiểu dữ liệu được sử dụng trong chương trình. Việc nắm vững cách sử dụng linux nm command sẽ giúp bạn gỡ lỗi, tối ưu hóa hiệu suất và hiểu sâu hơn về cách các chương trình hoạt động. Hãy thử nghiệm với các tùy chọn khác nhau của nm để khám phá thêm nhiều thông tin thú vị. Đừng ngại thử nghiệm với các file khác nhau để làm quen với cú pháp và kết quả trả về. Hy vọng bài viết này đã cung cấp cho bạn một cái nhìn tổng quan và hữu ích về lệnh nm. Chúc bạn thành công trên con đường khám phá thế giới Linux!

```
Last Updated : 17/10/2025