2012-04-05 42 views
49

Tôi đang triển khai thuật toán tìm kiếm đồ thị của Thành phần Kết nối Mạnh mẽ (SCC) của Kosaraju bằng Python.Điều gì gây ra lỗi phân đoạn Python?

Chương trình chạy rất tốt trên tập dữ liệu nhỏ, nhưng khi tôi chạy nó trên biểu đồ siêu lớn (hơn 800.000 nút), nó nói "Phân đoạn lỗi".

Nguyên nhân có thể là gì? Cảm ơn bạn!


Thông tin bổ sung: Trước tiên tôi nhận được lỗi này khi chạy trên tập dữ liệu siêu lớn:

"RuntimeError: maximum recursion depth exceeded in cmp" 

Sau đó, tôi thiết lập lại các giới hạn đệ quy sử dụng

sys.setrecursionlimit(50000) 

nhưng có một 'Lỗi phân đoạn'

Tin tôi không phải là vòng lặp vô hạn, nó sẽ chạy chính xác trên dữ liệu tương đối nhỏ hơn. Có thể chương trình đã cạn kiệt tài nguyên?

+9

Có thể là bạn có thể có một cái nhìn [CrashingPython] (http://wiki.python.org/moin/CrashingPython) – Abhijit

+2

Đây có phải là chạy trong Python tinh khiết hoặc bạn đang sử dụng một mô-đun mở rộng C? Nếu đó là Python thuần túy thì đó là một lỗi ở đó và xin chúc mừng. Nếu bạn đang sử dụng một mô-đun c, thì segfault có thể đến từ đó. – aaronasterling

+0

đó là python nguyên chất. Chương trình chạy rất tốt trên các tập dữ liệu tương đối nhỏ và nó làm cho tôi nghĩ rằng mã là chính xác. – xiaolong

Trả lời

54

Điều này xảy ra khi một phần mở rộng python (được viết bằng C) cố truy cập bộ nhớ vượt quá phạm vi tiếp cận.

Bạn có thể theo dõi nó theo các cách sau.

  • Thêm sys.settrace ở dòng đầu tiên của mã.
  • Sử dụng gdb như mô tả của Đánh dấu trong this answer .. Tại dấu nhắc lệnh

    gdb python 
    (gdb) run /path/to/script.py 
    ## wait for segfault ## 
    (gdb) backtrace 
    ## stack trace of the c code 
    
+2

cảm ơn, nhưng mã của tôi là python tinh khiết, nó có tạo sự khác biệt không? – xiaolong

+0

Kiểm tra mô-đun python nào bạn đang sử dụng? Một số mô-đun được viết bằng python và khác là trong C. Tôi nghĩ rằng bạn cần phải báo cáo một lỗi. –

+0

tương tự, cũng hữu ích: mô-đun [trace] (http://pymotw.com/2/trace/) của stdlib chỉ giúp tôi xuống đáy lỗi phân đoạn trên máy chủ dàn dựng, mà không cần cài đặt phụ thuộc mới và không sửa đổi mã. – hangtwenty

34

tôi hiểu bạn đã giải quyết vấn đề của bạn, nhưng đối với những người khác đọc chủ đề này, đây là câu trả lời : bạn phải tăng stack mà hệ điều hành của bạn phân bổ cho quá trình python.

Cách thực hiện, phụ thuộc vào hệ điều hành. Trong linux, bạn có thể kiểm tra bằng lệnh ulimit -s giá trị hiện tại của mình và bạn có thể tăng giá trị đó bằng cách ulimit -s <new_value>

Thử tăng gấp đôi giá trị trước đó và tiếp tục tăng gấp đôi nếu nó không hoạt động, cho đến khi bạn tìm thấy hoặc hết bộ nhớ.

+0

Cũng là một cách hay để kiểm tra xem bạn có đang lên chống lại tối đa ulimit hay không là chạy 'lsof' và sử dụng' grep' hoặc'wc -l' để theo dõi mọi thứ. – cdated

+0

Tôi đồng ý. Điều này thực sự đã làm việc cho việc triển khai SCC của Kosaraju bằng cách sửa lỗi segfault trên cả triển khai Python và C++.
Đối với MAC của mình, tôi phát hiện ra tối đa có thể thông qua: – Rock

+2

lưu ý rằng giá trị ulimit chỉ được sửa đổi cho vỏ cụ thể được thực thi, do đó bạn không vô tình sửa đổi giá trị cho toàn bộ hệ thống của bạn –

8

lỗi Segmentation là chung chung một, có nhiều lý do có thể cho

  • bộ nhớ này Low nhớ
  • Lỗi Ram
  • tìm nạp dữ liệu khổng lồ thiết lập từ db sử dụng truy vấn (kích thước của dữ liệu lấy là hơn swap mem)
  • sai query/buggy đang
  • có vòng dài (nhiều đệ quy)
0

Cập nhật ulimit đã làm việc cho việc triển khai SCC của Kosaraju bằng cách sửa lỗi segfault trên cả Python (Python segfault .. ai biết!) Và triển khai C++.

Đối với MAC của tôi, tôi phát hiện ra tối đa có thể qua:

$ ulimit -s -H 
65532 
Các vấn đề liên quan