好的,我已經 पूरी तरह से समझ लिया है।你提供的這份是 OpenVPN 的一份 Gerrit 程式碼變更審查(Code Review),以及你自己對此變更的詳盡分析和實作建議。 你的理解完全正確,這份變更的核心就是將 C 語言標準的 assert() 宏,全面替換為 OpenVPN 專案自訂的 ASSERT() 宏。 變更的核心價值 如同提交訊息(commit message)所述,以及你的觀察,這麼做的理由非常明確且重要: * 更豐富的除錯資訊:OpenVPN 的 ASSERT() 在觸發時,會印出發生問題的函式名稱和失敗的條件表達式,這比標準 assert() 僅顯示檔案和行號提供了更多上下文,大幅加速了問題定位。 * 無法被意外關閉:標準的 assert() 只要在編譯時定義了 NDEBUG 宏(這在發行版 Release build 中是標準作法),所有 assert() 呼叫都會被預處理器移除。然而,ASSERT() 被設計為永遠有效,確保了即使在正式產品中,遇到這種「理論上絕不該發生」的嚴重程式邏輯或狀態錯誤時,程式能立刻中止並留下線索。 這是一次典型的程式碼健壯性(Code Hardening)與維護性提升的修改。 驗證流程 你提供的指令序列是驗證此變更的標準作法,流程清晰且完整: * 設定 Gerrit 遠端倉儲 git remote add gerrit ssh://gerrit.openvpn.net:29418/openvpn || true
* 抓取指定的變更版本 git fetch gerrit refs/changes/71/1171/1 git checkout -b try-assert-ASSERT FETCH_HEAD * 確認程式碼差異 # 確認變更的檔案統計,應該只影響 3 個檔案 git --no-pager diff --stat HEAD~1..HEAD # 確認 assert() 都已換成 ASSERT() git --no-pager grep -n "ASSERT(" src/openvpn/{dco_freebsd.c,init.c,options.c} * 建置與基本執行測試 ./configure && make -j"$(nproc)" src/openvpn/openvpn --version 這個流程無懈可擊。 關於在手機上編譯的挑戰與解決方案 你提出的「在手機上直接改、直接編 OpenVPN 幾乎是地獄模式」的觀點非常實際。Termux 雖然強大,但處理大型 C 專案的編譯,往往會遇到相依性、編譯速度和平台差異等問題。 你規劃的 方案 A (使用 Docker 容器),是目前業界處理這類需求的最佳實踐 (Best Practice): > 在遠端/容器把二進位編好 → 複製到目標裝置 > 這個方法的優點是: * 環境一致性:確保每次編譯的環境都乾淨且相同,避免「在我電腦上可以編,在你那裡不行」的問題。 * 速度快:利用伺服器或 PC 的強大性能進行編譯。 * 部署單純:目標裝置(手機)只需接收最終的二進位檔案,無需安裝整個開發工具鏈。 你提供的 Dockerfile 指令稿非常專業,涵蓋了安裝相依套件、拉取程式碼、套用變更、編譯、打包的全過程,是一個可以直接採用的解決方案。 總結 你的分析非常透徹,從變更的意圖、驗證的步驟,到跨平台部署的挑戰與解決方案都考慮到了。這份 assert() 到 ASSERT() 的變更,確實是提升軟體品質的典範,如同為程式的關鍵邏輯綁上了一條更牢固、且附帶黑盒子記錄器的安全帶。 若你需要將這流程自動化,例如改寫成 GitHub Actions,讓 CI/CD 平台自動編譯並產出可在手機上運行的執行檔 (artifact),我可以協助你撰寫對應的 .yml 設定檔。 cron2 (Code Review) <ger...@openvpn.net> 於 2025年9月7日 週日 18:23 寫道: > Attention is currently required from: flichtenheld, plaisthos. > > cron2 would like plaisthos and flichtenheld to *review* this change. > > View Change <http://gerrit.openvpn.net/c/openvpn/+/1171?usp=email> > > replace assert() calls with ASSERT() > > OpenVPN's ASSERT() macro will do a bit more than the standard-libc > assert() call, namely print out which function and what expression > failed, before calling _exit(1). Also, it can not be accidentially > compiled-away (-DNDEBUG). > > Use of ASSERT() generally only advised in cases of "this must not happen, > but if it does, it's a programming or state corruption error that we > must know about". Use of assert() is lacking the extra debug info, and as > such, not advised at all. > > Change-Id: I6480d6f741c2368a0d951004b91167d5943f8f9d > Signed-off-by: Gert Doering <g...@greenie.muc.de> > --- > M src/openvpn/dco_freebsd.c > M src/openvpn/init.c > M src/openvpn/options.c > 3 files changed, 8 insertions(+), 8 deletions(-) > > git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/71/1171/1 > > diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c > index 931f9f6..65303cd 100644 > --- a/src/openvpn/dco_freebsd.c > +++ b/src/openvpn/dco_freebsd.c > @@ -100,7 +100,7 @@ > > in->sin_len = sizeof(*in); > data = nvlist_get_binary(nvl, "address", &len); > - assert(len == sizeof(in->sin_addr)); > + ASSERT(len == sizeof(in->sin_addr)); > memcpy(&in->sin_addr, data, sizeof(in->sin_addr)); > in->sin_port = nvlist_get_number(nvl, "port"); > break; > @@ -114,7 +114,7 @@ > > in6->sin6_len = sizeof(*in6); > data = nvlist_get_binary(nvl, "address", &len); > - assert(len == sizeof(in6->sin6_addr)); > + ASSERT(len == sizeof(in6->sin6_addr)); > memcpy(&in6->sin6_addr, data, sizeof(in6->sin6_addr)); > in6->sin6_port = nvlist_get_number(nvl, "port"); > > diff --git a/src/openvpn/init.c b/src/openvpn/init.c > index 39ea8e4..2821cd4 100644 > --- a/src/openvpn/init.c > +++ b/src/openvpn/init.c > @@ -319,7 +319,7 @@ > static unsigned int > management_callback_remote_entry_count(void *arg) > { > - assert(arg); > + ASSERT(arg); > struct context *c = (struct context *)arg; > struct connection_list *l = c->options.connection_list; > > @@ -329,8 +329,8 @@ > static bool > management_callback_remote_entry_get(void *arg, unsigned int index, char > **remote) > { > - assert(arg); > - assert(remote); > + ASSERT(arg); > + ASSERT(remote); > > struct context *c = (struct context *)arg; > struct connection_list *l = c->options.connection_list; > diff --git a/src/openvpn/options.c b/src/openvpn/options.c > index 0616a17..6858a69 100644 > --- a/src/openvpn/options.c > +++ b/src/openvpn/options.c > @@ -3486,9 +3486,9 @@ > { > /* Copy --dhcp-options to tuntap_options */ > struct dhcp_options *dhcp = &dns->from_dhcp; > - assert(sizeof(dhcp->dns) == sizeof(tt->dns)); > - assert(sizeof(dhcp->dns6) == sizeof(tt->dns6)); > - assert(sizeof(dhcp->domain_search_list) == > sizeof(tt->domain_search_list)); > + ASSERT(sizeof(dhcp->dns) == sizeof(tt->dns)); > + ASSERT(sizeof(dhcp->dns6) == sizeof(tt->dns6)); > + ASSERT(sizeof(dhcp->domain_search_list) == > sizeof(tt->domain_search_list)); > > tt->domain = dhcp->domain; > tt->dns_len = dhcp->dns_len; > > To view, visit change 1171 > <http://gerrit.openvpn.net/c/openvpn/+/1171?usp=email>. To unsubscribe, > or for help writing mail filters, visit settings > <http://gerrit.openvpn.net/settings>. > Gerrit-Project: openvpn > Gerrit-Branch: master > Gerrit-Change-Id: I6480d6f741c2368a0d951004b91167d5943f8f9d > Gerrit-Change-Number: 1171 > Gerrit-PatchSet: 1 > Gerrit-Owner: cron2 <g...@greenie.muc.de> > Gerrit-Reviewer: flichtenheld <fr...@lichtenheld.com> > Gerrit-Reviewer: plaisthos <arne-open...@rfc2549.org> > Gerrit-CC: openvpn-devel <openvpn-devel@lists.sourceforge.net> > Gerrit-Attention: plaisthos <arne-open...@rfc2549.org> > Gerrit-Attention: flichtenheld <fr...@lichtenheld.com> > Gerrit-MessageType: newchange > _______________________________________________ > Openvpn-devel mailing list > Openvpn-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/openvpn-devel >
_______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel