如果您是使用 Arrow 程式碼的開發人員,套件對 tidy eval 和 C++ 的使用需要可靠的除錯策略。在本文中,我們推薦幾種方法。
在區段錯誤後取得更詳細的 C++ 錯誤訊息
如果您在 RStudio IDE 中工作,當發生區段錯誤時,您的 R 會話將會中止。如果您在命令列 R 會話中重新執行您的程式碼,會話不會自動中止,因此可以複製伴隨區段錯誤的錯誤訊息。以下是一個在撰寫本文時存在的錯誤範例。
> S3FileSystem$create()
*** caught segfault ***
address 0x1a0, cause 'memory not mapped'
Traceback:
1: (function (anonymous, access_key, secret_key, session_token, role_arn, session_name, external_id, load_frequency, region, endpoint_override, scheme, background_writes) { .Call(`_arrow_fs___S3FileSystem__create`, anonymous, access_key, secret_key, session_token, role_arn, session_name, external_id, load_frequency, region, endpoint_override, scheme, background_writes)})(access_key = "", secret_key = "", session_token = "", role_arn = "", session_name = "", external_id = "", load_frequency = 900L, region = "", endpoint_override = "", scheme = "", background_writes = TRUE, anonymous = FALSE)
2: exec(fs___S3FileSystem__create, !!!args)
3: S3FileSystem$create()
此輸出提供 R 回溯追蹤;但是,它沒有提供任何關於區段錯誤起源的確切 C++ 程式碼行的資訊。為此,您需要執行附加 C++ 除錯器的 R。
執行附加 C++ 除錯器的 R 程式碼
由於 Arrow 的核心是 C++ 程式碼,因此當錯誤源自 C++ 而非 R 層時,除錯程式碼有時可能很棘手。如果您正在新增觸發 C++ 錯誤的程式碼(或在現有程式碼中找到錯誤),這可能會導致區段錯誤。如果您在 RStudio 中工作,會話將會中止,您可能無法檢索診斷和/或報告錯誤所需的錯誤訊息。一種解決方法是找到導致錯誤的程式碼,並執行附加 C++ 除錯器的 R。
如果您使用 macOS 並使用 Apple 安裝程式安裝 R,您將無法執行附加除錯器的 R;請參閱此處的指示,以了解原因和解決方法。
首先,使用您的除錯器載入 R。最常見的除錯器是 gdb
(通常在 Linux 上找到,有時在 macOS 上,或透過 MinGW 或 Cygwin 在 Windows 上)和 lldb
(預設的 macOS 除錯器)。
在我的情況下是 gdb
,但如果您使用 lldb
除錯器(例如,如果您在 Mac 上),只需在此處替換該命令即可。
R -d gdb
接下來,執行 R。
run
您現在應該在附加 C++ 除錯器的 R 會話中。這看起來會像正常的 R 會話,但帶有額外的輸出。
現在,執行您的程式碼 - 直接在會話中或從檔案中載入。如果程式碼導致區段錯誤,您將獲得額外的輸出,可用於診斷問題或作為額外資訊附加到問題。
這是先前範例中顯示的區段錯誤的除錯器輸出。您可以在此處看到觸發區段錯誤的確切行包含在輸出中。
> S3FileSystem$create()
Thread 1 "R" received signal SIGSEGV, Segmentation fault.
0x00007ffff0128369 in std::__atomic_base<long>::operator++ (this=0x178) at /usr/include/c++/9/bits/atomic_base.h:318
318 operator++() noexcept