DOCUMENT:Q106262 26-JUL-2001 [visualc] TITLE :FIX: Direction Flag Is Not Cleared When an Exception Occurs PRODUCT :Microsoft C Compiler PROD/VER:winnt: OPER/SYS: KEYWORDS:kbCRT kbVCkbbuglist kbfixlist ====================================================================== ------------------------------------------------------------------------------- The information in this article applies to: - The C Run-Time (CRT), included with: - *EDITOR Please do not choose this product*Microsoft Visual C++ 32-bit Edition* use 241, 265, 225, version 1.0 ------------------------------------------------------------------------------- SYMPTOMS ======== Functions called in an exception handler can cause unexpected behavior such as access violations. CAUSE ===== The direction flag bit may not be cleared when the exception occurs. RESOLUTION ========== Clear the direction flag bit within either the exception handler or the termination handler. The sample code shown below illustrates clearing the flag in an exception handler. STATUS ====== Microsoft has confirmed this to be a bug in the products listed at the beginning of this article. This problem was corrected in Visual C++ version 2.0. MORE INFORMATION ================ On Intel processors, the direction flag bit in the flags register modifies the behavior of the string instructions. When the direction flag (DF) is 0 (zero), the string instructions operate on incrementally higher addresses. When DF is 1, the string instructions operate on incrementally lower addresses. On Intel chips, DF can be set to 1 with the STD instruction and can be cleared to 0 with the CLD instruction. If a function sets DF to 1, it should clear DF before terminating. This allows all functions to make the assumption that DF is always 0. All C run-time functions correctly clear DF upon termination. However, if an exception occurs before a function has a chance to clear DF, the flag will still be set when the exception handler is executed. This will cause code in the handler (which assumes that DF is 0) to fail. The manner in which the code fails depends on what the code is trying to do. In the example shown below, the printf() function called in the exception handler causes a memory access violation. The problem can be worked around by clearing DF upon entry into an exception or termination handler. In the sample code shown below, the exception handler checks the value of the do_cld variable to determine whether or not it will clear DF. The do_cld variable is set to 0 or 1 depending on whether or not the CLD command-line argument is specified when the sample is run. To illustrate the problem with DF being set to 1, run the sample without any command-line arguments. To allow the sample to run correctly, specify the CLD command-line argument. Sample Code ----------- /* Compiler options needed: /D_X86_ */ #include #include #include #include int handling = 0; int do_cld = 0; LONG MyFilter(LPEXCEPTION_POINTERS except_pointers) { EXCEPTION_RECORD* er = except_pointers->ExceptionRecord; if (do_cld) { __asm cld } if (er->ExceptionCode==EXCEPTION_ACCESS_VIOLATION && handling==0) { handling = 1; printf("We're in the filter now and printing out a long" "string that's long enough to cause a problem\n"); handling = 0; return EXCEPTION_EXECUTE_HANDLER; } else return EXCEPTION_CONTINUE_SEARCH; } int main(int argc,char** argv) { if ( argc==2 && ((strcmp(argv[1],"cld")==0) || (strcmp(argv[1],"CLD")==0))) do_cld = 1; __try { printf("Starting the test\n"); memcpy((void*)4,(void*)0,8); printf("After exception"); } __except (MyFilter(GetExceptionInformation())) { printf("In the handler now\n"); } return 0; } Additional query words: 1.00 structured handling protection fault ====================================================================== Keywords : kbCRT kbVC kbbuglist kbfixlist Technology : kbVCsearch kbAudDeveloper kbCRT Version : winnt: Issue type : kbbug Solution Type : kbfix ============================================================================= THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY. Copyright Microsoft Corporation 2001.