Gỡ lỗi ứng dụng

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

Android Studio cung cấp trình gỡ lỗi cho phép bạn thực hiện các thao tác sau và nhiều thao tác khác:

  • Chọn một thiết bị để gỡ lỗi ứng dụng của bạn.
  • Đặt các điểm ngắt trong mã Java, Kotlin và C/C++ của bạn.
  • Kiểm tra các biến và đánh giá biểu thức trong thời gian chạy.

Trang này cung cấp hướng dẫn thực hiện các thao tác cơ bản trong trình gỡ lỗi. Để tìm hiểu thêm, hãy xem các tài liệu gỡ lỗi của IntelliJ IDEA.

Bật tính năng gỡ lỗi

Trước khi bắt đầu gỡ lỗi, bạn cần chuẩn bị như sau:

  • Bật tính năng gỡ lỗi trên thiết bị của bạn:

    Nếu bạn đang sử dụng trình mô phỏng, thì trình mô phỏng này sẽ bật theo mặc định. Tuy nhiên, đối với một thiết bị đã kết nối, bạn cần bật tính năng gỡ lỗi trong các tuỳ chọn dành cho nhà phát triển thiết bị.

  • Chạy một biến thể bản dựng có thể gỡ lỗi:

    Bạn phải sử dụng biến thể bản dựngdebuggable true trong cấu hình bản dựng. Thông thường, bạn có thể chỉ cần chọn biến thể "debug" (gỡ lỗi) mặc định có trong mọi dự án Android Studio (mặc dù biến thể này không hiện trong tệp build.gradle). Tuy nhiên, nếu xác định các loại bản dựng mới có thể gỡ lỗi, thì bạn phải thêm `debuggable true` vào loại bản dựng:

    Groovy

    android {
        buildTypes {
            customDebugType {
                debuggable true
                ...
            }
        }
    }
    

    Kotlin

    android {
        buildTypes {
            create("customDebugType") {
                debuggable = true
                ...
            }
        }
    }
    

    Thuộc tính này cũng áp dụng cho các mô-đun có mã C/C++. (Ngừng sử dụng thuộc tính jniDebuggable).

    Nếu ứng dụng của bạn phụ thuộc vào một mô-đun thư viện mà bạn cũng muốn gỡ lỗi, thì thư viện đó cũng phải được gói bằng debuggable true để giữ lại các biểu tượng gỡ lỗi. Để đảm bảo rằng các biến thể có thể gỡ lỗi của dự án ứng dụng nhận được biến thể có thể gỡ lỗi của mô-đun thư viện, hãy nhớ phát hành các phiên bản không mặc định của thư viện.

Bắt đầu gỡ lỗi

Bạn có thể bắt đầu một phiên gỡ lỗi như sau:

  1. Đặt một số điểm ngắt trong mã ứng dụng.
  2. Trong thanh công cụ, hãy chọn một thiết bị để gỡ lỗi ứng dụng của bạn trong trình đơn thả xuống giúp chọn thiết bị mục tiêu.

    Trình đơn thả xuống giúp chọn thiết bị mục tiêu.

    Nếu chưa định cấu hình thiết bị nào, thì bạn cần kết nối thiết bị qua USB hoặc tạo AVD để sử dụng Trình mô phỏng Android.

  3. Trong thanh công cụ, hãy nhấp vào biểu tượng Gỡ lỗi .

    Nếu bạn thấy hộp thoại hỏi xem bạn có muốn "chuyển từ chế độ Run (Chạy) sang Debug (Gỡ lỗi)" hay không, có nghĩa là ứng dụng của bạn đã chạy trên thiết bị và sẽ khởi động lại để bắt đầu gỡ lỗi. Nếu bạn muốn giữ nguyên phiên bản ứng dụng đang chạy, hãy nhấp vào Cancel Debug (Huỷ gỡ lỗi) và thay vào đó, hãy đính kèm trình gỡ lỗi vào một ứng dụng đang chạy.

    Nếu không, Android Studio sẽ tạo một APK, ký APK bằng một khoá gỡ lỗi, cài đặt APK này trên thiết bị mà bạn đã chọn và chạy APK đó. Nếu bạn thêm mã C và C++ vào dự án, Android Studio cũng chạy Trình gỡ lỗi LLDB trong cửa sổ Debug (Gỡ lỗi) để gỡ lỗi mã gốc.

  4. Nếu cửa sổ Debug (Gỡ lỗi) không mở, hãy chọn View > Tool Windows > Debug (Xem > Cửa sổ công cụ > Gỡ lỗi) (hoặc nhấp vào biểu tượng Gỡ lỗi trong công cụ thanh cửa sổ), sau đó nhấp vào thẻ Debugger (Trình gỡ lỗi), như minh hoạ trong hình 1.

    Hình 1. Cửa sổ Debugger (Trình gỡ lỗi), hiển thị luồng hiện tại và cây đối tượng của một biến

Đính kèm trình gỡ lỗi vào một ứng dụng đang chạy

Nếu ứng dụng của bạn đang chạy trên thiết bị, bạn có thể bắt đầu gỡ lỗi mà không cần khởi động lại ứng dụng như sau:

  1. Nhấp vào biểu tượng Đính kèm trình gỡ lỗi vào quy trình Android .
  2. Trong hộp thoại Choose Process (Chọn quy trình), hãy chọn quy trình bạn muốn đính kèm trình gỡ lỗi.

    Nếu đang sử dụng một trình mô phỏng hoặc thiết bị bị can thiệp hệ thống, bạn có thể chọn Show all processes (Hiển thị mọi quy trình) để xem mọi quy trình.

    Trong trình đơn thả xuống Use Android Debugger Settings from (Sử dụng các chế độ cài đặt trình gỡ lỗi Android từ), bạn có thể chọn một cấu hình chạy/gỡ lỗi hiện có. (Đối với mã C và C++, tuỳ chọn này cho phép bạn sử dụng lại LLDB Startup Commands (Lệnh LLDB thực thi khi khởi động), LLDB Post Attach Commands (Lệnh LLDB thực thi sau khi đính kèm) và thư mục biểu tượng trong cấu hình hiện có). Nếu bạn chưa có cấu hình chạy/gỡ lỗi, hãy chọn Create New (Tạo mới). Lựa chọn này sẽ bật trình đơn thả xuống Debug Type (Loại gỡ lỗi), tại đó bạn có thể chọn một loại gỡ lỗi khác. Theo mặc định, Android Studio sử dụng loại gỡ lỗi Auto (Tự động) để chọn tuỳ chọn trình gỡ lỗi tốt nhất cho bạn, dựa trên việc dự án của bạn có chứa mã Java hay C/C++ hay không.

  3. Nhấp vào OK.

    Cửa sổ Gỡ lỗi sẽ xuất hiện.

Lưu ý: Trình gỡ lỗi Android Studio và trình thu thập dữ liệu rác được tích hợp thoải mái. Máy ảo Android đảm bảo rằng mọi đối tượng mà trình gỡ lỗi biết được sẽ không thu thập dữ liệu cho đến khi trình gỡ lỗi ngắt kết nối. Điều này có thể dẫn đến việc tăng dần đối tượng theo thời gian trong khi trình gỡ lỗi được kết nối. Ví dụ: nếu trình gỡ lỗi thấy một luồng đang chạy, thì đối tượng Thread được liên kết sẽ không được thu thập rác cho đến khi trình gỡ lỗi ngắt kết nối, ngay cả khi đã kết thúc luồng đó.

Thay đổi loại trình gỡ lỗi

Vì có nhiều công cụ trình gỡ lỗi cần phải gỡ lỗi mã Java/Kotlin và mã C/C++ nên trình gỡ lỗi Android Studio cho phép bạn chọn loại trình gỡ lỗi để sử dụng. Theo mặc định, Android Studio sẽ quyết định trình gỡ lỗi nào cần sử dụng dựa trên ngôn ngữ mà Android Studio phát hiện trong dự án của bạn (với loại trình gỡ lỗi Auto (Tự động)). Tuy nhiên, bạn có thể chọn trình gỡ lỗi theo cách thủ công trong cấu hình gỡ lỗi (nhấp vào Run > Edit Configurations (Chạy > Chỉnh sửa cấu hình)) hoặc trong hộp thoại xuất hiện khi bạn nhấp vào Run > Attach debugger to Android process (Chạy > Đính kèm trình gỡ lỗi vào quy trình Android).

Sau đây là các loại gỡ lỗi hiện có:

Tự động
Chọn loại gỡ lỗi này nếu bạn muốn Android Studio tự động chọn tuỳ chọn tốt nhất cho mã bạn đang gỡ lỗi. Ví dụ: nếu bạn có bất kỳ mã C hoặc C++ nào trong dự án, Android Studio sẽ tự động sử dụng loại gỡ lỗi Dual (Kép). Nếu không, Android Studio sẽ sử dụng loại gỡ lỗi Java (Java).
Java
Chọn loại gỡ lỗi này nếu bạn chỉ muốn gỡ lỗi mã được viết trong Java hoặc Kotlin – trình gỡ lỗi Java sẽ bỏ qua mọi điểm ngắt hoặc đồng hồ bạn đã đặt trong mã gốc.
Mã gốc (chỉ dùng được với mã C/C++)
Chọn loại gỡ lỗi này nếu bạn chỉ muốn sử dụng LLDB để gỡ lỗi mã của mình. Khi sử dụng kiểu gỡ lỗi này, bạn sẽ không xem được phiên gỡ lỗi cho trình gỡ lỗi Java. Theo mặc định, LLDB chỉ kiểm tra mã gốc của bạn và bỏ qua các điểm ngắt trong mã Java. Nếu cũng muốn gỡ lỗi mã Java, bạn nên chuyển sang loại gỡ lỗi Auto (Tự động) hoặc Dual (Kép).

Tính năng gỡ lỗi gốc chỉ hoạt động trên những thiết bị đáp ứng các yêu cầu sau:

  • Thiết bị hỗ trợ run-as.

    Để kiểm tra xem thiết bị có hỗ trợ run-as hay không, hãy chạy lệnh sau trên màn hình shell ADB được kết nối với thiết bị của bạn:

    run-as your-package-name pwd
    

    Thay thế your-package-name bằng tên gói của ứng dụng. Nếu thiết bị hỗ trợ run-as, lệnh sẽ trả về mà không có lỗi nào.

  • Thiết bị đã bật ptrace.

    Để kiểm tra xem ptrace đã bật hay chưa, hãy chạy lệnh sau trên ADB shell được kết nối với thiết bị của bạn:

    sysctl kernel.yama.ptrace_scope
    

    Nếu bạn bật ptrace, lệnh này sẽ in giá trị 0 hoặc lỗi unknown key. Nếu bạn không bật ptrace, ứng dụng này sẽ in một giá trị không phải là 0.

Kép (chỉ dùng được với mã C/C++)
Chọn loại gỡ lỗi này nếu bạn muốn chuyển đổi giữa gỡ lỗi Java và mã gốc. Android Studio sẽ đính kèm cả trình gỡ lỗi Java và LLDB vào quy trình ứng dụng của bạn (một thẻ cho trình gỡ lỗi Java và một thẻ cho LLDB) để bạn có thể kiểm tra các điểm ngắt trong cả mã Java và mã gốc mà không cần khởi động lại ứng dụng hoặc đang thay đổi cấu hình gỡ lỗi của bạn.

Trong hình 2, hãy chú ý 2 thẻ ở bên phải của tiêu đề cửa sổ Debug (Gỡ lỗi). Vì ứng dụng có cả mã Java và mã C++, nên một thẻ để gỡ lỗi mã gốc và thẻ còn lại để gỡ lỗi mã Java, như được chỉ định bằng -java.

Hình 2. Thẻ để gỡ lỗi mã gốc và thẻ để gỡ lỗi mã Java

Lưu ý: Nếu đang gỡ lỗi mã gốc được trình biên dịch tối ưu hoá, bạn có thể nhận được thông báo cảnh báo sau: This function was compiled with optimizations enabled. Some debugger features may not be available. Khi sử dụng cờ tối ưu hoá, chẳng hạn như cờ -O, trình biên dịch sẽ sửa đổi mã đã biên dịch để giúp mã chạy hiệu quả hơn. Điều này có thể khiến trình gỡ lỗi báo cáo thông tin không mong muốn hoặc không chính xác vì trình gỡ lỗi khó liên kết mã đã biên dịch được tối ưu hoá với mã nguồn ban đầu. Vì lý do này, bạn nên tắt tính năng tối ưu hoá trình biên dịch trong khi gỡ lỗi mã gốc của bạn.

Sử dụng nhật ký hệ thống

Nhật ký hệ thống hiển thị các thông báo hệ thống trong khi bạn gỡ lỗi ứng dụng. Những thông báo này bao gồm thông tin từ các ứng dụng chạy trên thiết bị. Nếu bạn muốn sử dụng nhật ký hệ thống để gỡ lỗi ứng dụng của mình, hãy đảm bảo mã của bạn viết thông điệp nhật ký và in ra dấu vết ngăn xếp cho các trường hợp ngoại lệ khi ứng dụng của bạn đang trong giai đoạn phát triển.

Viết thông điệp nhật ký trong mã của bạn

Để viết thông điệp nhật ký trong mã của bạn, hãy sử dụng lớp Log. Thông điệp nhật ký giúp bạn hiểu được quy trình thực thi bằng cách thu thập kết quả gỡ lỗi hệ thống trong khi bạn tương tác với ứng dụng của mình. Thông điệp nhật ký có thể cho bạn biết phần nào trong đơn đăng ký của bạn không thành công. Để biết thêm thông tin về cách ghi nhật ký, hãy xem bài viết Viết và xem nhật ký.

Ví dụ sau cho thấy cách bạn có thể thêm thông điệp nhật ký để xác định xem thông tin trạng thái trước đó có hiển thị hay không khi hoạt động của bạn bắt đầu:

Kotlin

import android.util.Log
...
private val TAG: String = MyActivity::class.java.simpleName
...
class MyActivity : Activity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        if (savedInstanceState != null) {
            Log.d(TAG, "onCreate() Restoring previous state")
            /* restore state */
        } else {
            Log.d(TAG, "onCreate() No saved state available")
            /* initialize app */
        }
    }
}

Java

import android.util.Log;
...
public class MyActivity extends Activity {
    private static final String TAG = MyActivity.class.getSimpleName();
    ...
    @Override
    public void onCreate(Bundle savedInstanceState) {
       ...
       if (savedInstanceState != null) {
            Log.d(TAG, "onCreate() Restoring previous state");
            /* restore state */
        } else {
            Log.d(TAG, "onCreate() No saved state available");
            /* initialize app */
        }
    }
}

Trong quá trình phát triển, mã của bạn cũng có thể phát hiện các trường hợp ngoại lệ và ghi dấu vết ngăn xếp vào nhật ký hệ thống:

Kotlin

fun someOtherMethod() {
    try {
        ...
    } catch (e : SomeException) {
        Log.d(TAG, "someOtherMethod()", e)
    }
}

Java

void someOtherMethod() {
    try {
        ...
    } catch (SomeException e) {
        Log.d(TAG, "someOtherMethod()", e);
    }
}

Lưu ý: Xoá thông điệp nhật ký gỡ lỗi và lệnh gọi in dấu vết ngăn xếp khỏi mã khi bạn sẵn sàng phát hành ứng dụng. Bạn có thể làm việc này bằng cách đặt cờ DEBUG và đặt thông điệp nhật ký gỡ lỗi bên trong câu lệnh có điều kiện.

Xem nhật ký hệ thống

Bạn có thể xem và lọc dữ liệu gỡ lỗi cũng như các thông báo hệ thống khác trong cửa sổ Logcat. Ví dụ: bạn có thể thấy các thông báo khi việc thu thập rác diễn ra hoặc thông báo mà bạn thêm vào ứng dụng của mình bằng lớp Log.

Để sử dụng logcat, hãy bắt đầu gỡ lỗi và chọn thẻ Logcat (Logcat) trong thanh công cụ ở dưới cùng như hình 3.

Hình 3. Cửa sổ logcat có cài đặt bộ lọc

Để xem nội dung mô tả về logcat và các tuỳ chọn lọc về logcat, hãy xem bài viết Viết và xem nhật ký với logcat.

Làm việc với các điểm ngắt

Android Studio hỗ trợ một số loại điểm ngắt kích hoạt nhiều thao tác gỡ lỗi. Loại phổ biến nhất là điểm ngắt dòng sẽ tạm dừng việc thực thi ứng dụng của bạn trên một dòng mã được chỉ định. Trong khi tạm dừng, bạn có thể kiểm tra biến, đánh giá biểu thức, sau đó tiếp tục thực thi từng dòng để xác định nguyên nhân gây ra lỗi thời gian chạy.

Để thêm điểm ngắt dòng, hãy tiến hành như sau:

  1. Tìm dòng mã bạn muốn tạm dừng thực thi, sau đó nhấp vào máng xối bên trái dọc theo dòng mã đó hoặc đặt con nháy trên dòng và nhấn tổ hợp phím Control + F8 (trên máy Mac: nhấn tổ hợp phím Command + F8).
  2. Nếu ứng dụng của bạn đang chạy, bạn không cần cập nhật ứng dụng để thêm điểm ngắt – chỉ cần nhấp vào biểu tượng Đính kèm trình gỡ lỗi vào quy trình Android . Nếu không, hãy bắt đầu gỡ lỗi bằng cách nhấp vào biểu tượng Gỡ lỗi .

Hình 3. Một dấu chấm màu đỏ sẽ xuất hiện bên cạnh dòng khi bạn đặt một điểm ngắt

Khi việc thực thi mã của bạn đến điểm ngắt, Android Studio sẽ tạm dừng việc thực thi ứng dụng của bạn. Sau đó, bạn có thể sử dụng các công cụ trong thẻ Debugger (Trình gỡ lỗi) để xác định trạng thái của ứng dụng:

  • Để kiểm tra cây đối tượng cho một biến, hãy mở rộng cây đối tượng trong khung hiển thị Variables (Biến). Nếu khung hiển thị Variables (Biến) không hiển thị, hãy nhấp vào biểu tượng Khôi phục khung hiển thị biến .

  • Để đánh giá biểu thức tại điểm thực thi hiện tại, hãy nhấp vào biểu tượng Đánh giá biểu thức .

  • Để chuyển đến dòng tiếp theo trong mã (mà không nhập phương thức), hãy nhấp vào biểu tượng Bước qua .

  • Để chuyển đến dòng đầu tiên trong lệnh gọi phương thức, hãy nhấp vào biểu tượng Bước vào .

  • Để chuyển đến dòng tiếp theo bên ngoài phương thức hiện tại, hãy nhấp vào biểu tượng Bước ra .

  • Để tiếp tục chạy ứng dụng như bình thường, hãy nhấp vào biểu tượng Tiếp tục chương trình .

Nếu dự án của bạn sử dụng bất kỳ mã gốc nào, theo mặc định, loại gỡ lỗi Auto (Tự động) sẽ đính kèm cả trình gỡ lỗi Java và LLDB vào ứng dụng của bạn dưới dạng hai quy trình riêng biệt để bạn có thể chuyển đổi giữa việc kiểm tra Java và Các điểm ngắt C/C++ mà không khởi động lại ứng dụng hoặc thay đổi các chế độ cài đặt.

Lưu ý: Để Android Studio phát hiện điểm ngắt trong mã C hoặc C++, bạn cần sử dụng loại gỡ lỗi hỗ trợ LLDB, chẳng hạn như Auto (Tự động), Native (Gốc) hoặc Dual (Kép). Bạn có thể thay đổi loại gỡ lỗi mà Android Studio sử dụng bằng cách chỉnh sửa cấu hình gỡ lỗi. Để tìm hiểu thêm về các loại gỡ lỗi khác nhau, hãy đọc phần về cách sử dụng các loại gỡ lỗi khác.

Khi Android Studio triển khai ứng dụng của bạn trên thiết bị mục tiêu, cửa sổ Debug (Gỡ lỗi) sẽ mở ra cùng với một thẻ hoặc khung hiển thị phiên gỡ lỗi cho từng quy trình gỡ lỗi, như minh hoạ trong hình 4.

Hình 4. Gỡ lỗi mã gốc bằng LLDB

  1. Android Studio chuyển sang thẻ <your-module> khi trình gỡ lỗi LLDB gặp phải điểm ngắt trong mã C/C++ của bạn. Các ngăn Frames (Khung), Variables (Biến) và Watches (Đồng hồ) cũng có sẵn và hoạt động giống như khi bạn gỡ lỗi mã Java. Mặc dù ngăn Threads (Chuỗi) không hiển thị trong chế độ xem phiên LLDB, nhưng bạn có thể truy cập vào các quy trình ứng dụng bằng cách sử dụng danh sách thả xuống trong ngăn Frames (Khung). Bạn có thể tìm hiểu thêm về các ngăn này trong mục cách gỡ lỗi khung cửa sổbiến kiểm tra.

    Lưu ý: Trong khi kiểm tra một điểm ngắt trong mã gốc của bạn, hệ thống Android sẽ tạm ngưng máy ảo chạy mã byte Java của ứng dụng. Điều này có nghĩa là bạn không thể tương tác với trình gỡ lỗi Java hoặc truy xuất bất kỳ thông tin trạng thái nào từ phiên của trình gỡ lỗi Java trong quá trình kiểm tra điểm ngắt trong mã gốc.

  2. Android Studio chuyển sang thẻ <your-module>-java khi trình gỡ lỗi Java gặp một điểm ngắt trong mã Java.
  3. Khi gỡ lỗi bằng LLDB, bạn có thể sử dụng thiết bị đầu cuối LLDB trong khung hiển thị phiên LLDB để chuyển các tuỳ chọn dòng lệnh tới LLDB. Nếu có một số lệnh nhất định mà bạn muốn LLDB thực thi mỗi khi bắt đầu gỡ lỗi ứng dụng, ngay trước hoặc ngay sau khi trình gỡ lỗi đính kèm vào quy trình ứng dụng, bạn có thể thêm các lệnh đó vào cấu hình gỡ lỗi.

Trong khi gỡ lỗi mã C/C++, bạn cũng có thể đặt các loại điểm ngắt đặc biệt, gọi là điểm theo dõi, để tạm ngưng quy trình dùng ứng dụng khi ứng dụng đó tương tác với một khối bộ nhớ cụ thể. Để tìm hiểu thêm, hãy đọc phần cách thêm điểm theo dõi.

Xem và định cấu hình điểm ngắt

Để xem tất cả các điểm ngắt và định cấu hình các tuỳ chọn cài đặt về điểm ngắt, hãy nhấp vào biểu tượng Xem điểm ngắt ở bên trái của cửa sổ Debug (Gỡ lỗi). Cửa sổ Breakpoints (Điểm ngắt) sẽ xuất hiện, như minh hoạ trong hình 5.

Hình 5. Cửa sổ Breakpoints (Điểm ngắt) liệt kê tất cả các điểm ngắt hiện tại và có các chế độ cài đặt hành vi cho từng điểm ngắt

Cửa sổ Breakpoints (Điểm ngắt) cho phép bạn bật hoặc tắt từng điểm ngắt từ danh sách bên trái. Nếu bạn tắt điểm ngắt, Android Studio sẽ không tạm dừng ứng dụng của bạn khi ứng dụng đó gặp điểm ngắt đó. Chọn một điểm ngắt trong danh sách để định cấu hình các chế độ cài đặt. Trước tiên, bạn có thể định cấu hình để tắt một điểm ngắt và yêu cầu hệ thống bật điểm ngắt đó sau khi đến một điểm ngắt khác. Bạn cũng có thể định cấu hình xem có tắt điểm ngắt sau khi hệ thống đến điểm ngắt đó không. Để đặt điểm ngắt cho bất kỳ trường hợp ngoại lệ nào, hãy chọn Exception Breakpoints (Điểm ngắt cho ngoại lệ) trong danh sách các điểm ngắt.

Gỡ lỗi khung cửa sổ

Trong cửa sổ Debugger (Trình gỡ lỗi), ngăn Frames (Khung) cho phép bạn kiểm tra khung ngăn xếp khiến điểm ngắt hiện tại bị ảnh hưởng. Thao tác này cho phép bạn điều hướng và kiểm tra khung ngăn xếp, cũng như kiểm tra danh sách các luồng trong ứng dụng Android. Để chọn một luồng, hãy sử dụng bộ chọn luồng thả xuống và xem khung ngăn xếp của luồng đó. Khi bạn nhấp vào các phần tử trong khung, nguồn đó sẽ mở ra trong trình chỉnh sửa. Bạn cũng có thể tuỳ chỉnh bản trình bày luồng và xuất khung ngăn xếp như đã thảo luận trong hướng dẫn Khung.

Kiểm tra biến

Trong cửa sổ Debugger (Trình gỡ lỗi), ngăn Variables (Biến) cho phép bạn kiểm tra các biến khi hệ thống dừng ứng dụng của bạn trên một điểm ngắt và bạn chọn một khung từ ngăn Frames (Khung). Ngăn Variables (Biến) cũng cho phép bạn đánh giá các biểu thức đặc biệt bằng cách dùng các phương thức tĩnh và/hoặc biến có sẵn trong khung đã chọn.

Ngăn Watches (Đồng hồ) cung cấp chức năng tương tự, ngoại trừ biểu thức được thêm vào ngăn Watches (Đồng hồ) giữa các phiên gỡ lỗi. Bạn nên thêm đồng hồ cho các biến và trường mà bạn thường xuyên truy cập hoặc cung cấp các trạng thái hữu ích cho phiên gỡ lỗi hiện tại. Ngăn Variables (Biến) và Watches (Đồng hồ) xuất hiện như minh hoạ trong hình 5.

Để thêm một biến hoặc biểu thức vào danh sách Watches (Đồng hồ), hãy làm theo các bước sau:

  1. Bắt đầu gỡ lỗi.
  2. Trong ngăn Watches (Đồng hồ), hãy nhấp vào biểu tượng Thêm .
  3. Trong hộp văn bản xuất hiện, hãy nhập tên của biến hoặc biểu thức mà bạn muốn xem rồi nhấn phím Enter.

Để xoá một mục khỏi danh sách Watches (Đồng hồ), hãy chọn mục đó rồi nhấp vào biểu tượng Xoá .

Bạn có thể sắp xếp lại các thành phần trong danh sách Watches (Đồng hồ) bằng cách chọn một mục rồi nhấp vào biểu tượng Mũi tên lên hoặc Mũi tên xuống .

Hình 6. Ngăn Variables (Biến) và Watches (Đồng hồ) trong cửa sổ Debugger (Trình gỡ lỗi)

Thêm điểm xem

Trong khi gỡ lỗi mã C/C++, bạn có thể đặt các loại điểm ngắt đặc biệt, gọi là điểm theo dõi, có thể tạm ngưng quá trình xử lý ứng dụng của bạn khi ứng dụng đó tương tác với một khối bộ nhớ cụ thể. Ví dụ: nếu bạn đặt hai con trỏ vào một khối bộ nhớ và gán một điểm theo dõi cho bộ nhớ đó, hãy sử dụng con trỏ để truy cập khối bộ nhớ đó và kích hoạt điểm theo dõi.

Trong Android Studio, bạn có thể tạo điểm theo dõi trong thời gian chạy bằng cách chọn một biến cụ thể, nhưng LLDB chỉ gán điểm theo dõi cho khối bộ nhớ mà hệ thống phân bổ cho biến đó, chứ không phải cho chính biến. Hành động này khác với việc thêm một biến vào ngăn Watches (Đồng hồ), cho phép bạn quan sát giá trị của một biến nhưng không cho phép bạn tạm ngưng quy trình ứng dụng khi hệ thống sẽ đọc hoặc thay đổi giá trị của bộ nhớ trong bộ nhớ.

Lưu ý: Khi ứng dụng của bạn thoát khỏi một hàm và hệ thống loại bỏ các biến cục bộ của ứng dụng đó khỏi bộ nhớ, thì bạn cần phải gán lại mọi điểm theo dõi mà bạn đã tạo cho các biến đó.

Để đặt điểm xem, bạn phải đáp ứng các yêu cầu sau:

  • Trình mô phỏng hoặc thiết bị thực mục tiêu của bạn sử dụng CPU x86 hoặc x86_64. Nếu thiết bị của bạn sử dụng CPU ARM, thì bạn phải căn chỉnh ranh giới địa chỉ của biến trong bộ nhớ thành 4 byte đối với bộ xử lý 32 bit hoặc 8 byte đối với bộ xử lý 64 bit. Bạn có thể căn chỉnh một biến trong mã gốc bằng cách chỉ định __attribute__((aligned(num_bytes))) trong quá trình giảm tốc biến, như hiển thị bên dưới:
    // For a 64-bit ARM processor
    int my_counter __attribute__((aligned(8)));
    
  • Bạn đã chỉ định ba điểm xem hoặc ít hơn. Android Studio chỉ hỗ trợ tối đa 4 điểm theo dõi trên những thiết bị đích x86 hoặc x86_64. Các thiết bị khác có thể hỗ trợ ít điểm theo dõi hơn.

Lưu ý: Khi gỡ lỗi ứng dụng bằng các ABI ARM 32 bit, việc thêm điểm theo dõi hoặc di chuột qua các biến bên trong mã để điều tra giá trị của các biến đó có thể gây ra sự cố. Để khắc phục, vui lòng gỡ lỗi bằng cách sử dụng tệp nhị phân ARM, x86 hoặc x86_64. Vấn đề này sẽ được khắc phục trong bản phát hành Android Studio sắp tới.

Nếu đáp ứng các yêu cầu nêu trên, bạn có thể thêm điểm theo dõi như sau:

  1. Trong khi ứng dụng của bạn bị tạm ngưng trên một điểm ngắt, hãy chuyển đến ngăn Variables (Biến) trong khung hiển thii phiên LLDB của bạn.
  2. Nhấp chuột phải vào một biến chiếm khối bộ nhớ mà bạn muốn theo dõi và chọn Add Watchpoint (Thêm điểm theo dõi). Một hộp thoại định cấu hình điểm theo dõi sẽ xuất hiện, như minh hoạ trong hình 7.

    Hình 7. Thêm một điểm theo dõi vào một biến trong bộ nhớ

  3. Định cấu hình điểm theo dõi với các tuỳ chọn sau:
    • Enabled (Bật): Bạn hiện có thể bỏ chọn tuỳ chọn này nếu muốn Android Studio bỏ qua điểm theo dõi tại thời điểm này. Android Studio vẫn lưu điểm theo dõi của bạn để bạn có thể truy cập vào điểm theo dõi đó sau trong phiên gỡ lỗi.
    • Suspend (Tạm ngưng): Theo mặc định, hệ thống Android sẽ tạm ngưng quy trình ứng dụng của bạn khi truy cập một khối bộ nhớ mà bạn chỉ định cho một điểm theo dõi. Bạn có thể bỏ chọn tuỳ chọn này nếu không muốn sử dụng hành vi này. Khi đó, bạn sẽ có thêm các tuỳ chọn để tuỳ chỉnh hành vi khi hệ thống tương tác với điểm theo dõi của bạn: Log message to console (Ghi nhật ký thông báo vào bảng điều khiển) và Remove [the watchpoint] when hit (Xoá [điểm theo dõi] khi đến).
    • Access Type (Loại truy cập): Chọn xem ứng dụng của bạn có nên kích hoạt điểm theo dõi của bạn khi cố gắng Read (Đọc) hoặc Write (Ghi) vào khối bộ nhớ không mà hệ thống phân bổ cho biến. Để kích hoạt điểm theo dõi của bạn trên một lượt đọc hoặc ghi, hãy chọn Any (Bất kỳ).
  4. Nhấp vào Xong.

Để xem tất cả các điểm theo dõi của bạn và định cấu hình các chế độ cài đặt điểm theo dõi, hãy nhấp vào biểu tượng Xem điểm ngắt ở phía bên trái của cửa sổ Debug (Gỡ lỗi). Hộp thoại Breakpoints (Điểm ngắt) xuất hiện, như minh hoạ trong hình 8.

Hình 8. Hộp thoại Breakpoints (Điểm ngắt) liệt kê các điểm theo dõi hiện tại của bạn và bao gồm các chế độ cài đặt hành vi cho từng điểm

Sau khi bạn thêm điểm theo dõi, hãy nhấp vào biểu tượng Tiếp tục chương trình ở phía bên trái của cửa sổ Debug (Gỡ lỗi) để tiếp tục xử lý ứng dụng. Theo mặc định, nếu ứng dụng của bạn cố gắng truy cập một khối bộ nhớ mà bạn đã đặt điểm theo dõi, thì hệ thống Android sẽ tạm ngưng quy trình ứng dụng của bạn và biểu tượng điểm theo dõi xuất hiện bên cạnh dòng mã ứng dụng của bạn đã thực thi gần đây nhất, như minh hoạ trong hình 9.

Hình 9. Android Studio cho biết dòng mã mà ứng dụng của bạn thực thi ngay trước khi kích hoạt điểm theo dõi

Xem và thay đổi định dạng hiển thị giá trị tài nguyên

Ở chế độ gỡ lỗi, bạn có thể xem các giá trị tài nguyên và chọn một định dạng hiển thị khác cho các biến trong mã Java. Khi thẻ Variables (Biến) hiển thị và một khung đã chọn, hãy làm như sau:

  1. Trong danh sách Variables (Biến), hãy nhấp chuột phải vào bất kỳ vị trí nào trên một dòng tài nguyên để hiển thị danh sách thả xuống.
  2. Trong danh sách thả xuống, hãy chọn View as (Xem dưới dạng) và chọn định dạng bạn muốn sử dụng.

    Các định dạng có sẵn phụ thuộc vào loại dữ liệu của tài nguyên mà bạn chọn. Bạn có thể thấy một hoặc nhiều tuỳ chọn sau đây:

    • Class (Loại): Hiển thị định nghĩa loại.
    • toString: Định dạng chuỗi hiển thị.
    • Object (Đối tượng): Hiển thị định nghĩa đối tượng (thực thể của một loại).
    • Array (Mảng): Hiển thị ở định dạng mảng.
    • Timestamp (Dấu thời gian): Hiển thị ngày và giờ như sau: yyyy-mm-dd hh:mm:ss.
    • Auto (Tự động): Android Studio sẽ chọn định dạng phù hợp nhất tuỳ vào loại dữ liệu.
    • Binary (Nhị phân): Hiển thị giá trị nhị phân bằng cách sử dụng số không và số nhị phân.
    • MeasureSpec: Giá trị được chuyển từ đơn vị gốc đến thư mục con đã chọn. Xem MeasureSpec.
    • Hex (Thập lục phân): Hiển thị dưới dạng giá trị thập lục phân.
    • Primitive (Gốc): Hiển thị dưới dạng giá trị số bằng loại dữ liệu gốc.
    • Integer (Số nguyên): Hiển thị một giá trị số thuộc loại Integer.

Bạn có thể tạo một định dạng tuỳ chỉnh (trình kết xuất loại dữ liệu) như sau:

  1. Nhấp chuột phải vào giá trị tài nguyên.
  2. Chọn View as (Xem dưới dạng).
  3. Chọn Tạo. Hộp thoại Java Data Type Renderers (Trình hiển thị loại dữ liệu Java) sẽ hiển thị.
  4. Hãy làm theo hướng dẫn tại Trình kết xuất loại dữ liệu Java.