Gỡ lỗi [Debugging] là một trong những điều khủng khiếp, khó tìm nhất trong phát triển phần mềm, nhưng điều ngang trái thay nó lại là một trong những điều quan trọng bậc nhất trong vòng đời phát triển phần mềm. Chắc chắn trong giai đoạn phát triển, mọi thành viên lập trình đều phải tự gỡ lỗi mã của mình, điều này là không thể tránh khỏi
Có rất nhiều cách để gỡ lỗi một ứng dụng viết ra. Một phương pháp được sử dụng rất phổ biến biến đó là sử dụng câu lệnh "in" trong các trường hợp để xem nó chạy như thế nào trong khi thực hiện chương trình. Tuy nhiên, phương pháp này xảy ra nhiều vấn đề, chẳng hạn như việc muốn lấy giá trị của biến thì phải thêm mã vào, v. v. => Quá phức tạp. Hơn nữa, cách này chỉ dùng tạm bợ cho những chương trình nhỏ, mã tầm nhìn trở lại, thì ok, khi mà sang một chương trình lớn hơn, có nhiều tệp hơn, thì nó lại là một vấn đề lớn hơn
Vì vậy, chúng ta đã có một trình giải quyết lỗi để giải quyết vấn đề đó cho. Nó giúp chúng ta tìm ra các lỗi trong một ứng dụng bằng các lệnh bên ngoài, do đó không có sự thay đổi nào đối với mã. Như đã đề cập ở trên, mình muốn giới thiệu các bạn module PDB - module tích hợp bên trong python [không cần thiết phải cài đặt từ nguồn bên ngoài], thông qua bài viết "Có PDB, python debug không còn khó khăn"
Mời các bạn đọc tiếp
Các lệnh thao tác cơ bản
Để hiểu các lệnh hoặc công cụ chính có trong PDB, mình sẽ viết một đoạn chương trình nho nhỏ, vui vui, cơ bản, sau đó thử gỡ lỗi bằng lệnh PDB. Bằng những điều này, chúng ta sẽ thấy rõ ràng hơn, chính xác hơn mỗi lệnh của PDB sẽ làm gì
1 -> list_crush = ['Lê', 'Thi', 'Thiên', 'Mỹ']
2 love_codes = [1111112, 2111014, 3451524, 4512244]
3
4 def show_list_crush[]:
5 print['List crush: ']
6 for crush in list_crush:
7 print[crush]
8
9 print["code of loves: "]
10 for code in love_codes:
11 print[code]
[Pdb]
9list_crush = ['Lê', 'Thi', 'Thiên', 'Mỹ']
love_codes = [1111112, 2111014, 3451524, 4512244]
def show_list_crush[]:
print['List crush: ']
for crush in list_crush:
print[crush]
print["Code of loves: "]
for code in love_codes:
print[code]
def main[]:
show_list_crush[]
if __name__ == "__main__":
main[]
Kết quả của đoạn script trên
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
Đoạn mã trên chắc mình cũng không cần phải giải thích nhiều, vì nó là cơ bản đối với người làm về python rồi, nó không có gì khó cũng như cú pháp phức tạp cả. Bạn không cần phải hiểu đoạn lệnh đang thực thi, mục đích chính của mình thực hiện một số lệnh PDB dựa trên chương trình này. Ok, started thôi
Sử dụng PDB yêu cầu sử dụng Giao diện dòng lệnh [CLI], do đó bạn phải chạy ứng dụng của mình từ
[Pdb] list 4, 6
0 hoặc [Pdb] list 4, 6
1Run the command under here in CLI of you
python -m pdb loves.py
In the command on, file name
[Pdb] list 4, 6
2, because that you will please chèn tên tệp của bạn thay cho [Pdb] list 4, 6
2Lưu ý.
[Pdb] list 4, 6
4 là một lá cờ và nó thông báo cho Python rằng một mô-đun cần phải được nhập khẩu; Chạy xong lệnh sẽ hiển thị như thế này
> /home/nguyenmanh/projects/test/loves.py[1][]
-> list_crush = ['Lê', 'Thi', 'Thiên', 'Mỹ']
[Pdb]
Đầu ra sẽ luôn có cùng cấu trúc. Nó sẽ bắt đầu với đường dẫn thư mục đến tệp mã nguồn. Sau đó, trong trích dẫn, nó sẽ cho biết số dòng từ tệp mà PDB hiện đang trỏ tới, trong trường hợp của mình là
[Pdb] list 4, 6
5. Dòng tiếp theo, bắt đầu bằng ký hiệu [Pdb] list 4, 6
6, cho biết dòng đang được trỏ đếnTo close PDB, only to enter
[Pdb] list 4, 6
7 or [Pdb] list 4, 6
8Một vài điều cần lưu ý, nếu chương trình của bạn có các tham số đầu vào, bạn cũng có thể chuyển chúng qua dòng lệnh. Ví dụ, nếu chương trình của mình yêu cầu 3 bắt đầu từ người dùng, thì lệnh của mình sẽ như thế này
list_crush = ['Lê', 'Thi', 'Thiên', 'Mỹ']
love_codes = [1111112, 2111014, 3451524, 4512244]
def show_list_crush[]:
print['List crush: ']
for crush in list_crush:
print[crush]
print["Code of loves: "]
for code in love_codes:
print[code]
def main[]:
show_list_crush[]
if __name__ == "__main__":
main[]
4Tiếp tục, nếu trước đó bạn đã đóng PDB thông qua lệnh
[Pdb] list 4, 6
7 hoặc [Pdb] list 4, 6
8, sau đó chạy lại tệp mã thông qua PDB. Sau đó, chạy lệnh sau trong dòng lệnh PDBlist_crush = ['Lê', 'Thi', 'Thiên', 'Mỹ']
love_codes = [1111112, 2111014, 3451524, 4512244]
def show_list_crush[]:
print['List crush: ']
for crush in list_crush:
print[crush]
print["Code of loves: "]
for code in love_codes:
print[code]
def main[]:
show_list_crush[]
if __name__ == "__main__":
main[]
7Đầu ra trông như thế này
1 -> list_crush = ['Lê', 'Thi', 'Thiên', 'Mỹ']
2 love_codes = [1111112, 2111014, 3451524, 4512244]
3
4 def show_list_crush[]:
5 print['List crush: ']
6 for crush in list_crush:
7 print[crush]
8
9 print["code of loves: "]
10 for code in love_codes:
11 print[code]
[Pdb]
Hiển thị 11 dòng đầu tiên của chương trình cho bạn, với dấu
[Pdb] list 4, 6
6 hướng về dòng hiện tại đang được gỡ lỗi. Tiếp theo, hãy thử lệnh này trong dòng lệnh PDB[Pdb] list 4, 6
Lệnh này sẽ chỉ hiển thị các dòng được chọn, trong trường hợp này là các dòng từ 4 đến 6. This is the start up
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
1Gỡ lỗi với điểm ngắt
Một điều quan trọng tiếp theo mà chúng ta sẽ hiểu là
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12. List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 thường được sử dụng cho các chương trình lớn hơn, nhưng để hiểu rõ hơn về nó, chúng ta sẽ tìm hiểu cách nó hoạt động dựa trên ví dụ cơ bản bên trên. List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 là các vị trí cụ thể mà chúng tôi khai báo trong mã của mình. Mã của tôi chạy đến vị trí đó và sau đó tạm dừng. Những điểm này được tự động gán số bởi PDBCó các tùy chọn sau đây để tạo ra
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12- Theo number lines [Theo số dòng]
- Bằng cách khai báo hàm [Bằng cách khai báo hàm]
- By a condition [Theo một điều kiện]
To khai báo
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 theo số dòng, hãy chạy lệnh sau trong dòng lệnh PDBList crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
7Lệnh này chèn một
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 vào dòng mã thứ 8, nó sẽ tạm dừng chương trình một khi nó chạy tới điểm đó. This command start is display isList crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
0Để khai báo các
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 trên một hàm, hãy chạy lệnh sauList crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
1Để chèn một điểm dừng theo cách này, bạn phải khai báo nó bằng tên tệp và sau đó là tên hàm. This thing output as after
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
2Như bạn đã thấy,
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 này đã được tự động gán số 2 và dòng số là 4 - chính là tại dòng hàm được khai báoList crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 cũng có thể được khai báo bởi một điều kiện. Trong trường hợp đó, chương trình sẽ chạy cho đến khi điều kiện sai và sẽ tạm dừng khi điều kiện đó trở thành đúng. Run command afterList crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
3Điều này sẽ theo dõi giá trị của biến
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
71 trong suốt quá trình thực thi và chỉ ngắt khi giá trị của nó là "Thi" ở dòng 6Để xem tất cả các
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 mà mình đã khai báo dưới dạng danh sách, hãy chạy lệnhList crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
4Kết quả sẽ có dạng
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
5Cuối cùng, làm thế nào chúng ta có thể vô hiệu hóa, kích hoạt và xóa một
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 cụ thể tại bất kỳ trường hợp nào. Run command afterList crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
6Lệnh trên sẽ vô hiệu hóa
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 2, nhưng sẽ không xóa nó khỏi phiên bản gỡ lỗiBạn sẽ thấy số
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 bị vô hiệu hóaList crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
7Cho phép xem lại danh sách tất cả các
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 để xem giá trị "End" cho List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 2List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
4đầu ra
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
9To activate
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
12 2python -m pdb loves.py
0Và một lần nữa, đây là đầu ra
python -m pdb loves.py
1Bây giờ, nếu bạn có trong danh sách tất cả các điểm ngắt, giá trị "Kết thúc" của điểm ngắt 2 sẽ hiển thị
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
79Bây giờ chúng ta hãy xóa breakpoint 1
python -m pdb loves.py
2Kết quả
python -m pdb loves.py
3Nếu chúng ta vào lại danh sách các breakpoint, thì bây giờ sẽ chỉ hiển thị 2 breakpoint. Please check by
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
00python -m pdb loves.py
4Đúng như mong đợi
Trước khi làm điều tiếp theo, tôi muốn hiển thị kết quả khi chạy mã cho đến khi điểm ngắt được đặt. Để làm điều đó, hãy xóa tất cả các điểm dừng trước đó và khai báo một điểm dừng khác thông qua dòng lệnh PDB
Xóa tất cả các breakpoint
5python -m pdb loves.py
Sau đó, nhập "y" và nhấn "ENter". You will see the output results
6python -m pdb loves.py
Khai báo một breakpoint mới
Mình sẽ chạy đến khi giá trị của biến
71 bằng "Thi". Vì vậy, về cơ bản, chương trình sẽ tạm dừng trước chữ "Lê"List crush: Lê Thi Thiên Mỹ code of loves: 1111112 2111014 3451524 4512244
3List crush: Lê Thi Thiên Mỹ code of loves: 1111112 2111014 3451524 4512244
Run for to breakpoint
Để chạy mã, hãy sử dụng
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
02, lệnh này sẽ thực thi mã này cho đến khi chạm điểm ngắt hoặc kết thúcpython -m pdb loves.py
8You will see
python -m pdb loves.py
9Chương trình chạy cho đến breakpoint và tạm dừng, bây giờ tùy thuộc vào chúng ta muốn thay đổi bất cứ điều gì, kiểm tra các kiến trúc hoặc nếu chúng ta muốn chạy tập lệnh cho đến khi hoàn thành. Please run command
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
02Kết quả
> /home/nguyenmanh/projects/test/loves.py[1][]
-> list_crush = ['Lê', 'Thi', 'Thiên', 'Mỹ']
[Pdb]
0Trong kết quả trên, có thể thấy chương trình tiếp tục từ điểm dừng, chạy lại phần còn lại và sau đó khởi động lại để cho phép chúng tôi gỡ lỗi thêm nếu muốn. Bây giờ chuyển sang phần tiếp theo
Lưu ý quan trọng. Trước khi di chuyển về phía trước, hãy xóa tất cả các điểm dừng bằng cách chạy lệnh
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
04, sau đó nhập List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
05 vào dòng lệnh PDBChức năng Next và Step
Cuối cùng, nhưng không làm mất đi phần quan trọng, chúng tôi nghiên cứu về
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
06 và List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
07. Chúng ta sẽ sử dụng rất thường xuyên khi bạn bắt đầu gỡ lỗi các ứng dụng của mình, vì vậy hãy tìm hiểu kỹ về nó nhéCác hàm
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
06 và List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
07 được sử dụng để lặp trong suốt quá dòng mã của chúng ta theo từng dòng. Có sự khác biệt giữa cả hai. Trong khi lặp, nếu List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
07 gặp lệnh gọi hàm, nó sẽ chuyển đến dòng đầu tiên nơi định nghĩa hàm đó và cho chúng ta xác định chính xác những gì có ở bên trong hàm. trong khi đó, List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
06 khi được gọi nó sẽ chạy tất cả các dòng của hàm đó trong một lần duy nhất và tạm dừng lệnh gọi hàm tiếp theoBối rối?
Run back program
python -m pdb loves.py
Bây giờ hãy nhập vào
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
07 và tiếp tục cho đến khi kết thúc chương trình> /home/nguyenmanh/projects/test/loves.py[1][]
-> list_crush = ['Lê', 'Thi', 'Thiên', 'Mỹ']
[Pdb]
2Bây giờ, hãy chạy lại toàn bộ chương trình, nhưng lần này sử dụng lệnh
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
06 thay vì List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
07> /home/nguyenmanh/projects/test/loves.py[1][]
-> list_crush = ['Lê', 'Thi', 'Thiên', 'Mỹ']
[Pdb]
3Bây giờ chúng ta sẽ phân tích xem chúng ta khác nhau như thế nào. Đối với
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
07, bạn có thể thấy rằng khi List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
16 nó chuyển bên trong hàm và lặp qua List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
07, chúng ta sẽ thấy chính xác những gì xảy ra bên trong mỗi bướcTuy nhiên,
List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
06 khi gọi hàm List crush:
Lê
Thi
Thiên
Mỹ
code of loves:
1111112
2111014
3451524
4512244
19, nó sẽ không cho chúng ta thấy điều gì xảy ra bên trong hàm đó [tức là gọi một cách thẳng tiến], và sau đó trực tiếp kết quả cuối cùng trong một bước duy nhấtkết luận
Trong phần hướng dẫn này, tôi đã hướng dẫn các bạn đang tìm hiểu về các cách giải quyết lỗi với mô-đun python PDB. Hi vọng sẽ giúp các bạn lập trình python được nhiều lỗi hơn =]]