C 出現exception異常的位置如何定位?

2021-05-23 09:59:04 字數 4014 閱讀 8004

有人問過我,在windows系統,如果c++的new產生異常exception,怎麼才能知道出錯的位置。

最簡單的 方法是用 _set_new_handler。

如果不是 new 產生的, 或者程式非法訪問記憶體了。

經過試驗,可以先用__try __except捕獲它,

在處理函式裡面輸出callstack呼叫堆疊,以及exe、dll的名字、位址、範圍等資訊。

處理完了返回exception_continue_search,交給c++的try catch來繼續處理。

#include

#include

class win32_tool_help  

public:

win32_tool_help();

virtual ~win32_tool_help();

static int show_module_list();

#include

#include

// construction/destruction

win32_tool_help::win32_tool_help()

win32_tool_help::~win32_tool_help()

int win32_tool_help::show_module_list()

handle hsnap = createtoolhelp32snapshot( 

th32cs_snapmodule,

getcurrentprocessid( )

moduleentry32 me;

me.dwsize = sizeof(me);

bool ret = module32first( hsnap, &me );

while (true == ret)

_tprintf( 

text("hmodule = %p, modbaseaddr = %p, modbasesize = %08x, ")

text("szexepath = %s, szmodule = %s /n"), 

me.hmodule, me.modbaseaddr, me.modbasesize,

me.szexepath, me.szmodule

ret = module32next( hsnap, &me );

closehandle( hsnap );

return 0;

class win32_stack_walk  

public:

win32_stack_walk();

virtual ~win32_stack_walk();

static int start( lpexception_pointers ep );

#include

#pragma comment( lib, "imagehlp.lib" )

// construction/destruction

win32_stack_walk::win32_stack_walk()

win32_stack_walk::~win32_stack_walk()

int win32_stack_walk::start( lpexception_pointers ep )

const dword machine_type = image_file_machine_i386;

handle hprocess, hthread;

hprocess = getcurrentprocess();

hthread = getcurrentthread();

stackframe frame = ;

lpvoid contextrecord = null;

pread_process_memory_routine readmemoryroutine = null; // &readprocessmemory;

pfunction_table_access_routine functiontableaccessroutine = &symfunctiontableaccess;

pget_module_base_routine getmodulebaseroutine = &symgetmodulebase;

ptranslate_address_routine translateaddress = null;

bool ret = false;

struct handle_frame_addr while( ret == true );

return 0;

#define show_esp()  /

do while(0);

void show_diag_info( lpexception_pointers ep )

win32_stack_walk::start( ep );

win32_tool_help::show_module_list();

void raise01( )

printf("%s/n", "raise");

context ctx_s = ;

exception_pointers ep_s;

lpexception_pointers ep = &ep_s;

ep_s.contextrecord = &ctx_s;

show_esp();

memset( 0, 1, 1 );

void raise02( )

printf("%s/n", "raise");

context ctx_s = ;

exception_pointers ep_s;

lpexception_pointers ep = &ep_s;

ep_s.contextrecord = &ctx_s;

show_esp();

throw -1;

int seh_filter01( dword ec, lpexception_pointers ep )

printf("%s/n", "seh_filter");

show_esp();

show_diag_info( ep );

return exception_execute_handler;

int seh_filter02( dword ec, lpexception_pointers ep )

printf("%s/n", "seh_filter");

show_esp();

show_diag_info( ep );

return exception_continue_search;

void test01()

dword ec = 0;

lpexception_pointers ep = null;

__try

raise01();

__except( ec = getexceptioncode(), ep = getexceptioninformation(), seh_filter01( ec, ep ) )

printf("%s/n", "test01->__except");

show_esp();

void test02_inner()

dword ec = 0;

lpexception_pointers ep = null;

__try

raise02();

__except( ec = getexceptioncode(), ep = getexceptioninformation(), seh_filter02( ec, ep ) )

printf("%s/n", "test01->__except");

show_esp();

void test02()

trytest02_inner();

catch(...)

printf("%s/n", "c++ catch(...)");

int main(int argc, char* argv)

test01();

test02();

return 0;

異常Exception的處理

我們可以很簡單的認為將異常定義為程式執行時所發生的非正常狀況。我們必須清楚的認知到異常不同於錯誤,錯誤發生後程式是不能編譯的,而異常一般是再程式編譯途中所發生的。第一種處理方式,異常捕獲 try catch arrayindexoutofbound ception e 第二種處理方式,丟擲異常 in...

Exception異常處理

1.exception 前言 在ios裡對異常的處理及捕獲,並沒有其它語言裡那麼常見,相信很多ios程式設計師都知道,更多的時候是對記憶體的的檢測與分析,檢測相關記憶體方面的問題。捕獲後傳送至伺服器,並且友好提示使用者錯誤,或則直接回滾到使用者操作前,阻止應用程式的崩潰。2.exception處理 ...

關於異常EXCEPTION

命名未命名的內部異常,在編譯時處理 例如 declare exp exception pragma exception init exp,2292 begin exception when exp then end 拋出自定義異常 語法 error number範圍 20000至 20999 mes...