Share via


/SAFESEH (影像擁有安全例外處理常式)

更新:2007 年 11 月

/SAFESEH[:NO]

指定 /SAFESEH 時,若連結器也可產生影像安全例外處理常式的表格,將只會產生一個影像。此表格會告訴作業系統,哪個例外處理常式對於影像而言是有效的。

/SAFESEH 只有在連結 x86 目標時才有效。在已經註明有例外處理常式的平台上不支援 /SAFESEH。例如,在 x64 和 Itanium 上,所有例外處理常式都已在 PDATA 中註明。ML64.exe 有支援可加入發出 SEH 資訊 (XDATA 和 PDATA) 至影像的附註,可以讓您一直回溯到 ml64 函式。如需詳細資訊,請參閱 MASM for x64 (ml64.exe)

若未指定 /SAFESEH,則在所有模組都與安全例外處理常式功能相容時,連結器將會產生包含安全例外處理常式表格的影像。若有任何模組與安全例外處理常式功能不相容,產生的影像將不包含安全例外處理常式的表格。若 /SUBSYSTEM 指定 WINDOWSCE 或某個 EFI_* 選項,連結器將不會嘗試產生包含安全例外處理常式表格的影像,因為這些子系統都不會使用該資訊。

若已指定 /SAFESEH:NO,即使所有模組都能與安全例外處理常式功能相容,連結器也不會產生包含安全例外處理常式表格的影像。

連結器無法產生影像最常見的原因,是連結器的一個或多個輸入檔 (模組) 與安全例外處理常式功能不相容。模組與安全例外處理常式不相容的原因,通常是因為它是以舊版的 Visual C++ 編譯器建立的。

您也可以透過使用 .SAFESEH,將函式註冊為結構化例外處理常式。

在 Microsoft Visual C++ 2005 中是不可能將現有的二進位標示為有安全例外處理常式 (或沒有例外處理常式);安全例外處理的相關資訊都必須在建置執行時間加入。

連結器建置安全例外處理常式表格的能力,是取決於使用 C Runtime 程式庫的應用程式。若您以 /NODEFAULTLIB 連結,並且需要安全例外處理常式的表格,就需要提供載入組態結構 (例如在 loadcfg.c CRT 原始程式檔內可發現的載入組態結構),其中包含針對 Visual C++ 定義的所有項目。例如:

#include <windows.h>
extern DWORD_PTR __security_cookie;  /* /GS security cookie */

/*
 * The following two names are automatically created by the linker for any
 * image that has the safe exception table present.
*/
 
extern PVOID __safe_se_handler_table[]; /* base of safe handler entry table */
extern BYTE  __safe_se_handler_count;  /* absolute symbol whose address is
                                           the count of table entries */
typedef struct {
    DWORD       Size;
    DWORD       TimeDateStamp;
    WORD        MajorVersion;
    WORD        MinorVersion;
    DWORD       GlobalFlagsClear;
    DWORD       GlobalFlagsSet;
    DWORD       CriticalSectionDefaultTimeout;
    DWORD       DeCommitFreeBlockThreshold;
    DWORD       DeCommitTotalFreeThreshold;
    DWORD       LockPrefixTable;            // VA
    DWORD       MaximumAllocationSize;
    DWORD       VirtualMemoryThreshold;
    DWORD       ProcessHeapFlags;
    DWORD       ProcessAffinityMask;
    WORD        CSDVersion;
    WORD        Reserved1;
    DWORD       EditList;                   // VA
    DWORD_PTR   *SecurityCookie;
    PVOID       *SEHandlerTable;
    DWORD       SEHandlerCount;
} IMAGE_LOAD_CONFIG_DIRECTORY32_2;

const IMAGE_LOAD_CONFIG_DIRECTORY32_2 _load_config_used = {
    sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32_2),
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    &__security_cookie,
    __safe_se_handler_table,
    (DWORD)(DWORD_PTR) &__safe_se_handler_count
};

在 Visual Studio 開發環境中設定這個連結器選項

  1. 開啟專案的 [屬性頁] 對話方塊。如需詳細資訊,請參閱設定 Visual C++ 專案屬性

  2. 按一下 [連結器] 資料夾。

  3. 按一下 [命令列] 屬性頁。

  4. 在 [其他選項] 方塊中輸入選項。

以程式設計方式設定這個連結器選項

請參閱

參考

設定連結器選項

連結器選項