C++�쳣���Ƶ�ʵ�ַ�ʽ�Ϳ�������

����

baiy.cn

��

���Ҽ���ǰ��ʼд��C++�����淶��ָ����һ��ʱ�����Ѿ��滮��Ҫ��������һƪ���� C++ �쳣���Ƶ������ˡ�û�뵽ʱ�������Ժ����л���������β�Ͳ��� :-)��

�����Ǿ俪���ף�����ǡ���ij���ʹ��ǡ�������ԡ� ��ÿ����ְ�� C++ ����Ա��˵����һ��������׼����Ҫ�������㣬�ͱ���Ҫ�˽�������ÿ�����Ե�ʵ�ַ�ʽ����ʱ�տ������쳣���������漰�����ײ����ݣ������� C++ ���ָ߼������н���������͸�����յIJ��֡����Ľ��ھ����������ײ�ϸ�ڵ�ǰ���£����� C++ ����һո�����ԣ���������ʵ�ֿ�����

��

�����߳�

���̺��̵߳ĸ������Ÿ�λ�������Ѷ������ꡣ�������ֻ�������һ��伸����Ҫ���
  1. һ�������п���ͬʱ���������̡߳�
    ��
  2. ����ͨ����Ϊ�߳��Dz���ϵͳ��ʶ������С����ִ�к͵��ȵ�λ����Ҫ����˵���� Green Thread ���� Fiber��OS Kernel ����ʶҲ��Щ�����ĵ��ȣ���
    ��
  3. ͬһ�����еĶ����̹߳��������Σ������ͳ����������ݶΣ���̬��ȫ�ֱ���������չ�Σ��Ѵ洢��������ÿ���߳����Լ���ջ����ջ���ֽ�����ʱջ�������������оֲ���������ʱ����������������ֵ����ʱ�����ı����ȣ�����һ���������е�ijЩ������˵�Ƿdz���Ҫ�� ��������ע�⣬�����ᵽ�ĸ������Ρ������߼��ϵ�˵������������ijЩӲ���ܹ����߲���ϵͳ���ܲ�ʹ�ö�ʽ�洢������û��ϵ���������ᱣ֤��Щ�߼������ͼ�����ǰ��������ÿ�� C/C++ ����Ա��˵ʼ���dz����ġ�
    ��
  4. ���ڹ����˳�ջ�����������ڴ���ַ�Σ��̲߳��������Լ��ġ���̬������ȫ�֡�������Ϊ���ֲ���һȱ��������ϵͳͨ�����ṩһ�ֳ�Ϊ TLS��Thread Local Storage���������̱߳��ش洢�����Ļ��ơ�ͨ���û��ƿ���ʵ�����ƵĹ��ܡ�TLS ͨ�����߳̿��ƿ飨TCB���е�ij��ָ����ָ����һ��ָ�����飬�����е�ÿ��Ԫ�س�Ϊһ���ۣ�Slot����ÿ�����е�ָ����ʹ���߶��壬����ָ������λ�ã���ͨ����ָ���Ѵ洢�е�ij��ƫ�ƣ���

��

�����ĵ��úͷ���

�����������ع���һ��Ԥ��֪ʶ������������ʵ�ֺ����ĵ��úͷ��ء�һ����˵����������Ϊ��ǰ����ջ����ÿ����������һ��ջ���ܣ�Stack Frame������ջ���ܡ�������������Ҫ������
  1. ���ݲ�����ͨ���������ĵ��ò�����������������ջ���ܵ���ˡ�
  2. ���ݷ��ص�ַ�����߱������ߵ� return ����Ӧ�� return ������ȥ��ͨ��ָ���ú������õ���һ�����䣨�������е�ƫ�ƣ���
  3. ���ŵ����ߵĵ�ǰջָ�룺���������������ߵ����оֲ����������ָ������ߵ��ֳ���
  4. ���ŵ�ǰ�����ڵ����оֲ��������ǵ��𣿸ղ�˵�����оֲ�����ʱ�������Ǵ洢��ջ�ϵġ�

�����ٸ�ϰһ�㣺ջ��һ�֡������ȳ�����LIFO�������ݽṹ������ʵ���ϴ󲿷�ջ��ʵ�ֶ�֧���������ʡ�

���������������������ӣ�

������ FuncA��FuncB �� FuncC ����������ÿ��������������������ֵ��Ϊ����������ij�߳��ϵ�ijһʱ�����ڣ�FuncA ������ FuncB���� FuncB �ֵ����� FuncC���������ǵ�ջ���ܿ�����Ӧ����������


ͼ1 ��������ջ����ʾ��

������ͼ��ʾ�����������ź������𼶵��ã���������Ϊÿһ�����������Լ���ջ���ܣ�ջ�ռ��������ġ����ź������𼶷��أ��ú�����ջ����Ҳ�����������٣�ջ�ռ����������ͷš�˳��˵һ�䣬�ݹ麯����Ƕ�׵�������ͨ��Ҳ��ȡ��������ʱջ�ռ���ʣ���ߴ硣

����˳��������һ���������Լ����calling convention��������Լ��ͨ��ָ�������߽�����ѹ��ջ�У��������Ĵ����У���˳�����Լ�����ʱ��˭�������߻��DZ������ߣ���������Щ������ϸ�ڹ��̷�����Լ����

������˵һ�䣬������չʾ�ĺ���������������䡱�ķ�ʽ��ʵ�������ǣ��ڿ������Ż�ѡ���󣬱��������ܲ���Ϊһ�����������������ĺ�������ջ���ܣ�����������ʹ�úܶ��Ż����������������졣��������һ�� C/C++ ����Ա��˵���ﵽ�����������̶�ͨ�����㹻�ˡ�


��

C++ �����ĵ��úͷ���

���ȳ���һ�㣬����˵�� ��C++ ��������ָ��
  1. �ú������ܻ�ֱ�ӻ����ӵ��׳�һ���쳣�����ú����Ķ���������һ�� C++ ���루�����Ǵ�ͳ C����Ԫ�ڣ����Ҹú���û��ʹ�á�throw()���쳣��������
  2. ���߸ú����Ķ�����ʹ���� try �顣

��������������һ���ɡ�Ϊ���ܹ��ɹ��ز����쳣����ȷ������ջ���ˣ�stack unwind��������������Ҫ����һЩ���������ݽṹ����Ӧ�Ĵ������ơ����������������������쳣�������Ƶ�ջ���ܴ�����ʲô���ӣ�


ͼ2 C++��������ջ����ʾ��

��ͼ2�ɼ�����ÿ�� C++ ������ջ�����ж�����һЩ��������ϸ�۲��Ļ������ᷢ�֣��������Ķ���������һ�� EXP ���͵Ľṹ�塣��һ�������ͻᷢ�֣�����һ�����͵ĵ�������ʽ�ṹ��

  • piPrev ��Աָ����������һ���ڵ㣬����Ҫ�����ں�������ջ����������Ѱ��ƥ���� catch �飬������ջ���˹�����

  • piHandler ��Աָ�������쳣������ջ���������������ݽṹ����Ҫ�����ż����Źؼ����ݵı�����try��������tblTryBlocks ����ջ���˱�����tblUnwind����

  • nStep ��Ա������λ try �飬�Լ���ջ���˱���Ѱ����ȷ�����ڡ�

��Ҫ˵�����ǣ���������Ϊÿһ����C++ ����������һ�� EHDL �ṹ������ֻ��Ϊ�����ˡ�try�����ĺ������� tblTryBlocks ��Ա�����⣬�쳣����������Ϊÿ���߳�ά��һ��ָ����ǰ�쳣�������ܵ�ָ�롣��ָ��ָ���쳣��������������β��ͨ��������ij�� TLS �ۻ��������������õĵط���

���������ٿ�һ��ͼ2�������ٶ����е����ݽṹ����һ������ӡ�������ǻ��ں�������С������ϸ�������ǡ�

ע����Ϊ�˼������������������������ݽṹ�ڣ�����ʡ����һЩ�뻰���޹صij�Ա��

��

ջ���ˣ�Stack Unwind������

��ջ���ˡ��ǰ����쳣������������ C++ �е�һ���¸����Ҫ����ȷ�����쳣���׳������񲢴������������������ѽ����Ķ��󶼻ᱻ��ȷ��������������ռ�õĿռ��ᱻ��ȷ�ػ��ա�

������ջ���˻��Ƶ����룬�Լ� C++ ����֧�ֵġ���Դ���뼴��ʼ�������⣬ʹ�����������ܹ����׸����Ȳ�����Ҳ����ȫ�� setjmp/longjmp ���ã������ְ�ȫ��ʵ��Զ����ת�ˡ�������Ҳ�� C++ �쳣���������ڴ�����������Ψһһ�ֺ�����Ӧ�÷�ʽ�ˡ�

�������Ǿ������忴��������������ʵ��ջ���˻��Ƶģ�


ͼ3 C++ ջ���˻���

ͼ3�еġ�FuncUnWind�������ڣ�������ʵ�������Ժ�ɫ����ɫ������ʾ�����������ɵĴ������ɻ�ɫ�ͳ�ɫ������������ʱ����ͼ2�������� nStep ������ tblUnwind ��Ա���þ�ʮ�������ˡ�

nStep �������ڸ��ٺ����ھֲ������Ĺ��졢�����׶Ρ������ϱ�����Ϊÿ���������ɵ� tblUnwind �����Ϳ���������ջ���ơ����е� pfnDestroyer �ֶμ�¼�˶�Ӧ�׶�Ӧ��ִ�е�������������������ָ�룩��pObj �ֶ�����¼����֮����Ӧ�Ķ��� this ָ��ƫ�ơ��� pObj ��ָ��ƫ��ֵ���ϵ�ǰջ���ܻ�ַ��EBP��������Ҫ���� pfnDestroyer ��ָ���������� this ָ�룬�����������ɶԸö����������������� nNextIdx �ֶ���ָ����һ����Ҫ�����������ڵ��У��±꣩��

�ڷ����쳣ʱ���쳣���������ȼ��鵱ǰ����ջ�����ڵ� nStep ֵ����ͨ�� piHandler ȡ�� tblUnwind[] ����Ȼ���� nStep ��Ϊ�±��������У�ִ�и��ж���������������Ȼ��ת���� nNextIdx ָ������һ�У�ֱ�� nNextIdx Ϊ -1 Ϊֹ���ڵ�ǰ������ջ���˹������������쳣���������ص�ǰ����ջ������ piPrev ��ֵ���ݵ��쳣�������е���һ�ڵ��ظ�����������ֱ�����л��˹�������Ϊֹ��

ֵ��һ�����ǣ�nStep ��ֵ��ȫ�ڱ���ʱ����������ʱ����ִ�����ɴμ򵥵�������������ֵ��ͨ����ֱ�Ӹ�ֵ��CPU����ij���Ĵ����������⣬���������ڲ������Լ�ʹ����Ĭ�Ϲ��졢���������������������г�Ա�ͻ���Ҳʹ����Ĭ�Ϸ����������ͣ��䴴�������پ���Ӱ�� nStep ��ֵ��

ע����������ջ���˵Ĺ����У��������������ĵ��ö��ٴ��������쳣���쳣�е��쳣����������Ϊ��һ���쳣�������Ƶ�����ʧ�ܡ���ʱ���̽���ǿ�н�ֹ��Ϊ��ֹ��������������Ӧ�����п����׳��쳣������������ʹ�á�std::uncaught_exception()�������жϵ�ǰ�Ƿ����ڽ���ջ���ˣ���������һ��δ������δ��ȫ�������ϵ��쳣�������ǣ���Ӧ�����쳣���ٴ��׳���

��

�쳣��������

һ���쳣���׳�ʱ���ͻ��������� C++ ���쳣�������ƣ�


ͼ4 C++ �쳣��������

����һС���У������Ѿ������� nStep �����ڸ��ٶ������졢�������������á�ʵ���� nStep �����ܹ����ٶ��󴴽������ٽ׶����⣬���ܹ���ʶ��ǰִ�е��Ƿ��� try ���У��Լ���������ǰ�����ж��� try ���Ļ����������ĸ� try ���С�����ͨ����ÿһ�� try �������ںͳ��ڸ�Ϊ nStep ����һ��Ψһ ID ֵ����ȷ�� nStep �ڶ�Ӧ try ���ڵı仯ǡ�ڴ˷�Χ֮����ʵ�ֵġ�

�ھ���ʵ���쳣����ʱ�����ȣ�C++ �쳣���������鷢���쳣��λ���Ƿ��ڵ�ǰ������ij�� try ��֮�ڡ����������ͨ������ǰ������ nStep ֵ������ piHandler ָ�� tblTryBlocks[] ������Ŀ�н��з�ΧΪ [nBeginStep, nEndStep) �ıȶ������ɡ�

���磺��ͼ4 �е� FuncB �� nStep == 2 ʱ�������쳣����ͨ���ȶ� FuncB �� tblTryBlocks[] ������ 2��[1, 3)���ʸ��쳣������ FuncB �ڵĵ�һ�� try ���С�

���Σ������쳣������λ���ڵ�ǰ�����е�ij�� try ���ڣ�������ƥ���� tblTryBlocks[] ��Ӧ��Ŀ�е� tblCatchBlocks[] ����tblCatchBlocks[] ���м�¼����ָ�� try �����׳��ֵ����� catch ��������Ϣ���������� catch �����ܲ������쳣���ͼ�����ʼ��ַ����Ϣ��

���ҵ���һ��ƥ���� catch �飬�����Ƶ�ǰ�쳣���󵽴� catch �飬Ȼ����ת�������ڵ�ִַ�п��ڴ��롣

��������˵���쳣����λ�ò��ڵ�ǰ������ try ���ڣ��������� try ����û���뵱ǰ�쳣��ƥ���� catch �飬��ʱ�����ź���ջ������ piPrev ��ָ��ַ�������쳣�������е���һ���ڵ㣩�����ظ����Ϲ��̣�ֱ���ҵ�һ��ƥ���� catch ���򵽴��쳣���������׽ڵ㡣���ں��ߣ����dz�Ϊ������δ�������쳣������ C++ �쳣���������ԣ�δ�������쳣��һ�����ش��󣬽����µ�ǰ���̱�ǿ�ƽ�����

ע������Ȼ��ͼ4ʾ���е� tblTryBlocks[] ֻ��һ����Ŀ��������Ŀ�е� tblCatchBlocks[] Ҳֻ��һ�С�������ʵ�������У����������ж������ж�����¼���⼴��һ�������п����ж��� try �飬ÿ�� try �������ɸ���������֮���׵� catch �顣

ע�������ձ�׼�����ϵ����⣬�쳣ʱ��ջ�����ǰ������쳣�������������쳣�������������Ͻ��еġ�������Щ�����������������쳣��������һ���Խ���ջ���˵ġ����۾���ʵ��ʹ�������ַ�ʽ���������ڿ���һ���ڴ��ϸ����޵�Ƕ��ʽӦ�ã�ͨ�����ǰ��ձ�׼���������ⶼ��������ʲô���⡣

��ע��ʵ���� tblCatchBlocks �л���һЩ��Ϊ�ؼ���������ʡ�Ե��ֶΡ�����ָ���� catch ���쳣�������Ʒ�ʽ����ֵ���������죩����ַ�����û�ָ�룩�����ֶΣ��Լ��ںδ����ű����Ƶ��쳣���������������ڵ�ַ��ƫ��λ�ã�����Ϣ��

��
��

�쳣���׳�

�������������� C++ �쳣���������е�����һ�����ڣ��쳣���׳���


ͼ5 C++ �쳣�׳�

�ڱ���һ�� C++ ����ʱ���������Ὣ���� throw �����滻Ϊ�� C++ ����ʱ���е�ijһָ���������������ǽ��� __CxxRTThrowExp���뱾���ᵽ�������������ݽṹ��������һ������ʵ��Ӧ�������������������ƣ����ú�������һ���������Ͽɵ��ڲ��ṹ�����ǽ��� EXCEPTION �ṹ���������ṹ�а����˴��׳��쳣��������ʼ��ַ�������������������������Լ����� type_info ��Ϣ������û������ RTTI ���ƣ������������� RTTI ���ƻ�û���������νṹ��ʹ�����������쳣�����νṹ�����ܻ�Ҫ���������л����� type_info ��Ϣ���Ա�����Ӧ�� catch ������ƥ�䡣

��ͼ5�е�����ɫ��ͼ�ڣ�����ʹ�� C++ α����չʾ�˺��� FuncA �е� ��throw myExp(1);�� ���佫�����������շ����ɵ����ӡ�ʵ�����ڶ��������£�__CxxRTThrowExp ����������ǰ���������ᵽ�ġ��쳣�����������쳣������ջ���˵ȸ�����Ҫ���������������ɡ�

__CxxRTThrowExp ���Ƚ��գ������棩EXCEPTION ������Ȼ���� TLS��Current ExpHdl ���ҵ��뵱ǰ������Ӧ�� piHandler��nStep ���쳣�����������ݣ�������ǰ�������Ļ��������쳣������ջ���ˡ��ɴ������˰������׳���->��������->�����ˡ��Ȳ����������쳣�������ơ�

��

Windows �еĽṹ���쳣����

Microsoft Windows ����һ����Ϊ���ṹ���쳣�������Ļ��ƣ��dz������ġ��ڴ�����Υ���������Ի������Ǹû��Ƶ�һ�����֡�Windows �ṹ���쳣������ǰ�����۵� C++ �쳣���������о��˵�����֮����ͬ��ʹ�����Ƶ���ʽ�ṹʵ�֡����� Windows �µ�Ӧ�ó�����ֻ��ʹ�� SetUnhandledExceptionFilter API ע���쳣���������� FS:[0] ����ǰ�������� TLS: Current ExpHdl �Ⱥ��ٵĸĶ������ɽ������ִ����������ƺ϶�Ϊһ��������������ʮ�����ԣ�
  • ���ڿ�ֱ�ӽ�������ϵͳ�ṩ�Ļ��ƣ����Լ����� C++ �쳣��������ʵ�֡�
  • ʹ��catch (...)�� �����Բ�������ϵͳ�������쳣���磺���ڴ�����Υ�����ȵȣ���
  • ʹ����ϵͳ���쳣���������ܹ��������� C++ �쳣��

ʵ���ϣ������� Windows �µ� C++ ���������쳣���ƾ�ʹ�����ַ�ʽʵ�֡�

��
��

�쳣�������ƵĿ�������

���ˣ������������ز��������� C++ �쳣�������Ƶ�ʵ��ԭ�������ڱ��ĵĿ�ͷ���ᵽ����Ϊһ�� C++ ����Ա���˽���ijһ���Ե�ʵ��ԭ����Ҫ��Ϊ�˱���������ʹ�ø����ԡ�Ҫ�ﵽ����Ŀ�ģ���Ҫ���˽�ʵ��ԭ���Ļ����Ͻ���һЩ�����Ŀ�������������
��
����ʱ�俪���ռ俪��
EHDL������ʱ����ÿ��C++������һ�� EHDL ���������е� tblTryBlocks[] ��Ա���ں����а�������һ�� try ��ʱʹ�á�����������С�� 64 �ֽڡ�

��

C++ջ���� ���ߵ� O(1) Ч�ʣ�ÿ�ε���ʱ����3�ζ��������θ�ֵ��һ�� TLS ���ʡ�ÿ ��������ָ����һ�����ο���������������С�� 16 �ֽڡ�

��

step ���� ���ߵ� O(1) Ч��ÿ�ν��� try ������������/����һ��������������ֵ�� �ޣ��Ѽ��� C++ ջ�����е���Ӧ��Ŀ����

��

�쳣���׳���������ջ���� �쳣���׳���һ�� O(1) ���������ڵ��������н��в�����ջ����Ҳ��Ϊ O(1) ������

���쳣�����������ɱ�Ϊ O(m)������ m ���ڵ�ǰ��������ջ�У����׳��쳣��λ�õ���ƥ�� catch ��֮���������ĺ��������У����� try �飨������������Ч tblTryBlocks[]���ĺ���������

ջ���˵��ܳɱ�Ϊ O(n)������ n ���ڵ�ǰ��������ջ�У����׳��쳣��λ�õ���ƥ�� catch ��֮���������ĺ�����������

���쳣��������ǰ���豣���쳣����������������ָ������Ӧ�� type_info ��Ϣ��

�������ݶ����ߴ硢������ѡ��Ƿ����� RTTI�����쳣�������IJ������ݷ�ʽ����ֵ����ַ���������нϴ��仯������������С�� 256 �ֽڡ�

��

���Կ�������û���׳��쳣ʱ��C++ ���쳣����������ʮ����Ч�ġ������쳣���׳��󣬿��ܻ�����ǰ��������ջ�����ν������ɴ����αȽϣ�try����ƥ�䣩����������ͨ�����ᳬ����ʮ�Ρ����ڴ����� 15 ��ǰ�� CPU ��˵�����αȽ�Ҳֻ�� 1 ʱ�����ڣ������쳣������Ч�ʻ��Ǻܸߵġ�ջ���˵�Ч������ return ���������൱��

���ǵ���ʹ�Ǵ�ͳ�ĺ������á������������𼶷��ػ���Ҳ����û�д��۵ġ���Щ�����ھ��������������Կ��Խ��ܡ��ռ俪�����棬ÿ��C++ ������һ�� EHDL �ṹ����������ijЩ���������»���������Ŀ���ļ��ߴ����ڴ濪�������ǵ��������£����ǵ�Ӱ�첢���󣬵�Ҳû��С��������ȫ���Եij̶ȡ���������Ϊһ����Դ�ϸ����޵Ļ�������Ӧ�ó�������������Ҫ���ǹر��쳣������ RTTI �����Խ�Լ�洢�ռ䡣

�������۵���һ�ֵ��͵��쳣���Ƶ�ʵ�ַ�ʽ�����������������̿������Լ����Ż��͸Ľ��������������ij��벻���ܴ���

��

��

�쳣������ C++ ��ʮ�����õ�ո������֮һ���ھ������������£����Ƕ����������ı��ֺ�����������ʱ��Ч�ʡ��쳣��������������һ�ַ��ػ��ơ������۴��������̡�ģ�����ơ�����ϰ�߻���ʱ��Ч�ʵȽǶ���˵���������г����ĵ�˵����ǰ���£�ż������������������ͳ�� setjmp/longjmp �����⣬Ӧ��ֻ֤�������ڳ����Ĵ������������С�

���⣬���ڳ���ת��ʹ�ü����ڳ�����������������ά�����ڱ���������ҲӦ����������ʹ�á������쳣��һ����ʹ��˵�������ο���������������ʽ���쳣��

��

 

 

��Ȩ���� (C) 2004 - 2019, ���� (baiy.cn). ��������Ȩ��.
Copyright (C) 2004 - 2019, Bai Yang (baiy.cn). All Rights Reserved.

XMR ����: 851299mKHBZhEEkQfbVBM6NgvUbACdeBoNxqppeuUgfL9vi3f1JpXGWAfBThKMK6XT38wpUU9vPC8AYzxQUooGxt2wi38D7