include/SDL_log.h
author Sam Lantinga <slouken@libsdl.org>
Thu, 16 May 2013 00:43:22 -0700
changeset 7180 3733e68edbc3
parent 6885 700f1b25f77f
child 7191 75360622e65f
permissions -rw-r--r--
Fixed bug 1846 - _allmul implementation in SDL_stdlib.c doesn't clean up the stack

Colin Barrett

I see this manifest itself (VS2012 x86) as:

"Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."

in the first call to SDL_GetTicks in my application. The disassembly at the problem line is:

hires_now.QuadPart *= 1000;
00AD0792 push 0
00AD0794 push 3E8h
00AD0799 mov eax,dword ptr [ebp-10h]
00AD079C push eax
00AD079D mov ecx,dword ptr [hires_now]
00AD07A0 push ecx
00AD07A1 call _allmul (0AE7D40h)
00AD07A6 mov dword ptr [hires_now],eax
00AD07A9 mov dword ptr [ebp-10h],edx

Apparently _allmul should be popping the stack but isn't (other similar functions in SDL_stdlib.c - _alldiv and whatnot - DO pop the stack).

A 'ret 10h' at the end of _allmul appears to do the trick
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 
    22 /**
    23  *  \file SDL_log.h
    24  *  
    25  *  Simple log messages with categories and priorities.
    26  *
    27  *  By default logs are quiet, but if you're debugging SDL you might want:
    28  *
    29  *      SDL_LogSetAllPriority(SDL_LOG_PRIORITY_WARN);
    30  *
    31  *  Here's where the messages go on different platforms:
    32  *      Windows: debug output stream
    33  *      Android: log output
    34  *      Others: standard error output (stderr)
    35  */
    36 
    37 #ifndef _SDL_log_h
    38 #define _SDL_log_h
    39 
    40 #include "SDL_stdinc.h"
    41 
    42 #include "begin_code.h"
    43 /* Set up for C function definitions, even when using C++ */
    44 #ifdef __cplusplus
    45 /* *INDENT-OFF* */
    46 extern "C" {
    47 /* *INDENT-ON* */
    48 #endif
    49 
    50 
    51 /**
    52  *  \brief The maximum size of a log message
    53  *
    54  *  Messages longer than the maximum size will be truncated
    55  */
    56 #define SDL_MAX_LOG_MESSAGE 4096
    57 
    58 /**
    59  *  \brief The predefined log categories
    60  *
    61  *  By default the application category is enabled at the INFO level,
    62  *  the assert category is enabled at the WARN level, test is enabled
    63  *  at the VERBOSE level and all other categories are enabled at the 
    64  *  CRITICAL level.
    65  */
    66 enum
    67 {
    68     SDL_LOG_CATEGORY_APPLICATION,
    69     SDL_LOG_CATEGORY_ERROR,
    70     SDL_LOG_CATEGORY_ASSERT,
    71     SDL_LOG_CATEGORY_SYSTEM,
    72     SDL_LOG_CATEGORY_AUDIO,
    73     SDL_LOG_CATEGORY_VIDEO,
    74     SDL_LOG_CATEGORY_RENDER,
    75     SDL_LOG_CATEGORY_INPUT,
    76     SDL_LOG_CATEGORY_TEST,
    77 
    78     /* Reserved for future SDL library use */
    79     SDL_LOG_CATEGORY_RESERVED1,
    80     SDL_LOG_CATEGORY_RESERVED2,
    81     SDL_LOG_CATEGORY_RESERVED3,
    82     SDL_LOG_CATEGORY_RESERVED4,
    83     SDL_LOG_CATEGORY_RESERVED5,
    84     SDL_LOG_CATEGORY_RESERVED6,
    85     SDL_LOG_CATEGORY_RESERVED7,
    86     SDL_LOG_CATEGORY_RESERVED8,
    87     SDL_LOG_CATEGORY_RESERVED9,
    88     SDL_LOG_CATEGORY_RESERVED10,
    89 
    90     /* Beyond this point is reserved for application use, e.g.
    91        enum {
    92            MYAPP_CATEGORY_AWESOME1 = SDL_LOG_CATEGORY_CUSTOM,
    93            MYAPP_CATEGORY_AWESOME2,
    94            MYAPP_CATEGORY_AWESOME3,
    95            ...
    96        };
    97      */
    98     SDL_LOG_CATEGORY_CUSTOM
    99 };
   100 
   101 /**
   102  *  \brief The predefined log priorities
   103  */
   104 typedef enum
   105 {
   106     SDL_LOG_PRIORITY_VERBOSE = 1,
   107     SDL_LOG_PRIORITY_DEBUG,
   108     SDL_LOG_PRIORITY_INFO,
   109     SDL_LOG_PRIORITY_WARN,
   110     SDL_LOG_PRIORITY_ERROR,
   111     SDL_LOG_PRIORITY_CRITICAL,
   112     SDL_NUM_LOG_PRIORITIES
   113 } SDL_LogPriority;
   114 
   115 
   116 /**
   117  *  \brief Set the priority of all log categories
   118  */
   119 extern DECLSPEC void SDLCALL SDL_LogSetAllPriority(SDL_LogPriority priority);
   120 
   121 /**
   122  *  \brief Set the priority of a particular log category
   123  */
   124 extern DECLSPEC void SDLCALL SDL_LogSetPriority(int category,
   125                                                 SDL_LogPriority priority);
   126 
   127 /**
   128  *  \brief Get the priority of a particular log category
   129  */
   130 extern DECLSPEC SDL_LogPriority SDLCALL SDL_LogGetPriority(int category);
   131 
   132 /**
   133  *  \brief Reset all priorities to default.
   134  *
   135  *  \note This is called in SDL_Quit().
   136  */
   137 extern DECLSPEC void SDLCALL SDL_LogResetPriorities(void);
   138 
   139 /**
   140  *  \brief Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO
   141  */
   142 extern DECLSPEC void SDLCALL SDL_Log(const char *fmt, ...);
   143 
   144 /**
   145  *  \brief Log a message with SDL_LOG_PRIORITY_VERBOSE
   146  */
   147 extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, const char *fmt, ...);
   148 
   149 /**
   150  *  \brief Log a message with SDL_LOG_PRIORITY_DEBUG
   151  */
   152 extern DECLSPEC void SDLCALL SDL_LogDebug(int category, const char *fmt, ...);
   153 
   154 /**
   155  *  \brief Log a message with SDL_LOG_PRIORITY_INFO
   156  */
   157 extern DECLSPEC void SDLCALL SDL_LogInfo(int category, const char *fmt, ...);
   158 
   159 /**
   160  *  \brief Log a message with SDL_LOG_PRIORITY_WARN
   161  */
   162 extern DECLSPEC void SDLCALL SDL_LogWarn(int category, const char *fmt, ...);
   163 
   164 /**
   165  *  \brief Log a message with SDL_LOG_PRIORITY_ERROR
   166  */
   167 extern DECLSPEC void SDLCALL SDL_LogError(int category, const char *fmt, ...);
   168 
   169 /**
   170  *  \brief Log a message with SDL_LOG_PRIORITY_CRITICAL
   171  */
   172 extern DECLSPEC void SDLCALL SDL_LogCritical(int category, const char *fmt, ...);
   173 
   174 /**
   175  *  \brief Log a message with the specified category and priority.
   176  */
   177 extern DECLSPEC void SDLCALL SDL_LogMessage(int category,
   178                                             SDL_LogPriority priority,
   179                                             const char *fmt, ...);
   180 
   181 /**
   182  *  \brief Log a message with the specified category and priority.
   183  */
   184 extern DECLSPEC void SDLCALL SDL_LogMessageV(int category,
   185                                              SDL_LogPriority priority,
   186                                              const char *fmt, va_list ap);
   187 
   188 /**
   189  *  \brief The prototype for the log output function
   190  */
   191 typedef void (*SDL_LogOutputFunction)(void *userdata, int category, SDL_LogPriority priority, const char *message);
   192 
   193 /**
   194  *  \brief Get the current log output function.
   195  */
   196 extern DECLSPEC void SDLCALL SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata);
   197 
   198 /**
   199  *  \brief This function allows you to replace the default log output
   200  *         function with one of your own.
   201  */
   202 extern DECLSPEC void SDLCALL SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata);
   203 
   204 
   205 /* Ends C function definitions when using C++ */
   206 #ifdef __cplusplus
   207 /* *INDENT-OFF* */
   208 }
   209 /* *INDENT-ON* */
   210 #endif
   211 #include "close_code.h"
   212 
   213 #endif /* _SDL_log_h */
   214 
   215 /* vi: set ts=4 sw=4 expandtab: */