Mercurial > sdl-ios-xcode
view src/SDL_error.c @ 3487:24d13328c44a
Eric Wing to Sam, hfutrell
This one is quite puzzling. I found a partial workaround, but I don't fully understand the reasons yet.
First, the console is complaining about not finding a nib for MainWindow.
I tried removing the entry for this in the info.plist, and the message went away, but it didn't really change anything.
Second, I stepped through this with the debugger and broke up some lines. It seems that the basic act of calling
view = [SDL_uikitopenglview alloc];
or even
view = [SDL_uikitview alloc]
will crash the program. The debugger messages plus the stack trace make me think it's not finding the SDL_uikitview classes for some reason. But I don't understand why this would be.
view = [UIView alloc] will not crash the program.
For kicks, I added a new definition of a class called SDL_object which subclasses NSObject in the same files as SDL_uikitopenglview and then call
view = [SDL_object alloc];
This does not crash the program.
So, then I modified SDL_object to subclass UIView. No crash.
Next, I made SDL_object subclass UIView<UITextFieldDelegate> . This crashes.
So it is the act of conforming to the UITextFieldDelegate protocol that is crashing things.
I don't understand why it would crash on alloc though. I'm guessing either a delegate needs to be set somewhere or one of the required methods needs to be implemented. But in the former case, I would not expect a crash, but a silent message to nil and something else doesn't work. And in the latter case, I would expect a compiler warning and an exception thrown instead of a crash.
Anyway, my temporary workaround is to change the interface declaration for SDL_uikitview to look like:
#if SDL_IPHONE_KEYBOARD
@interface SDL_uikitview : UIView<UITextFieldDelegate> {
#else
@interface SDL_uikitview : UIView {
#endif
And then disable the keyboard support in the SDL_config_iphoneos.h file.
/* enable iPhone keyboard support */
#define SDL_IPHONE_KEYBOARD 0
-Eric
On Nov 23, 2009, at 1:43 AM, Sam Lantinga wrote:
> I ran into a blocking startup crash with the Happy demo on iPhone OS 3.1.2 on my new iPhone:
>
> #0 0x323fea14 in _class_isInitialized
> #1 0x323fea68 in _class_initialize
> #2 0x32403e92 in prepareForMethodLookup
> #3 0x32401244 in lookUpMethod
> #4 0x323fea10 in _class_lookupMethodAndLoadCache
> #5 0x323fe746 in objc_msgSend_uncached
> #6 0x323feb26 in _class_initialize
> #7 0x323fea58 in _class_initialize
> #8 0x32403e92 in prepareForMethodLookup
> #9 0x32401244 in lookUpMethod
> #10 0x323fea10 in _class_lookupMethodAndLoadCache
> #11 0x323fe746 in objc_msgSend_uncached
> #12 0x000554dc in UIKit_GL_CreateContext at SDL_uikitopengles.m:103
> #13 0x0004f89e in SDL_GL_CreateContext at SDL_video.c:3155
> #14 0x000579e8 in GLES_CreateRenderer at SDL_renderer_gles.c:282
> #15 0x0004d7b8 in SDL_CreateRenderer at SDL_video.c:1509
> #16 0x00002bc2 in SDL_main at happy.c:156
> #17 0x000571b2 in -[SDLUIKitDelegate postFinishLaunch] at
> SDL_uikitappdelegate.m:77
> #18 0x313f9ef2 in __NSFireDelayedPerform
> #19 0x32567bb2 in CFRunLoopRunSpecific
> #20 0x3256735c in CFRunLoopRunInMode
> #21 0x32912cbe in GSEventRunModal
> #22 0x32912d6a in GSEventRun
> #23 0x32b6276e in -[UIApplication _run]
> #24 0x32b61472 in UIApplicationMain
> #25 0x00057088 in main at SDL_uikitappdelegate.m:50
>
> Any ideas?
>
> See ya!
> --
> -Sam Lantinga, Founder and President, Galaxy Gameworks LLC
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 24 Nov 2009 08:12:32 +0000 |
parents | b29eb7ce5352 |
children | f7b03b6838cb |
line wrap: on
line source
/* SDL - Simple DirectMedia Layer Copyright (C) 1997-2009 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Sam Lantinga slouken@libsdl.org */ #include "SDL_config.h" /* Simple error handling in SDL */ #include "SDL_error.h" #include "SDL_error_c.h" /* Routine to get the thread-specific error variable */ #if SDL_THREADS_DISABLED /* !!! FIXME: what does this comment mean? Victim of Search and Replace? */ /* The SDL_arraysize(The ),default (non-thread-safe) global error variable */ static SDL_error SDL_global_error; #define SDL_GetErrBuf() (&SDL_global_error) #else extern SDL_error *SDL_GetErrBuf(void); #endif /* SDL_THREADS_DISABLED */ #define SDL_ERRBUFIZE 1024 /* Private functions */ static const char * SDL_LookupString(const char *key) { /* FIXME: Add code to lookup key in language string hash-table */ return key; } /* Public functions */ void SDL_SetError(const char *fmt, ...) { va_list ap; SDL_error *error; /* Copy in the key, mark error as valid */ error = SDL_GetErrBuf(); error->error = 1; SDL_strlcpy((char *) error->key, fmt, sizeof(error->key)); va_start(ap, fmt); error->argc = 0; while (*fmt) { if (*fmt++ == '%') { while (*fmt == '.' || (*fmt >= '0' && *fmt <= '9')) { ++fmt; } switch (*fmt++) { case 0: /* Malformed format string.. */ --fmt; break; case 'c': case 'i': case 'd': case 'u': case 'o': case 'x': case 'X': error->args[error->argc++].value_i = va_arg(ap, int); break; case 'f': error->args[error->argc++].value_f = va_arg(ap, double); break; case 'p': error->args[error->argc++].value_ptr = va_arg(ap, void *); break; case 's': { int i = error->argc; const char *str = va_arg(ap, const char *); if (str == NULL) str = "(null)"; SDL_strlcpy((char *) error->args[i].buf, str, ERR_MAX_STRLEN); error->argc++; } break; default: break; } if (error->argc >= ERR_MAX_ARGS) { break; } } } va_end(ap); /* If we are in debug mode, print out an error message */ #ifdef DEBUG_ERROR fprintf(stderr, "SDL_SetError: %s\n", SDL_GetError()); #endif } /* This function has a bit more overhead than most error functions so that it supports internationalization and thread-safe errors. */ char * SDL_GetErrorMsg(char *errstr, unsigned int maxlen) { SDL_error *error; /* Clear the error string */ *errstr = '\0'; --maxlen; /* Get the thread-safe error, and print it out */ error = SDL_GetErrBuf(); if (error->error) { const char *fmt; char *msg = errstr; int len; int argi; fmt = SDL_LookupString(error->key); argi = 0; while (*fmt && (maxlen > 0)) { if (*fmt == '%') { char tmp[32], *spot = tmp; *spot++ = *fmt++; while ((*fmt == '.' || (*fmt >= '0' && *fmt <= '9')) && spot < (tmp + SDL_arraysize(tmp) - 2)) { *spot++ = *fmt++; } *spot++ = *fmt++; *spot++ = '\0'; switch (spot[-2]) { case '%': *msg++ = '%'; maxlen -= 1; break; case 'c': case 'i': case 'd': case 'u': case 'o': case 'x': case 'X': len = SDL_snprintf(msg, maxlen, tmp, error->args[argi++].value_i); msg += len; maxlen -= len; break; case 'f': len = SDL_snprintf(msg, maxlen, tmp, error->args[argi++].value_f); msg += len; maxlen -= len; break; case 'p': len = SDL_snprintf(msg, maxlen, tmp, error->args[argi++].value_ptr); msg += len; maxlen -= len; break; case 's': len = SDL_snprintf(msg, maxlen, tmp, SDL_LookupString(error->args[argi++]. buf)); msg += len; maxlen -= len; break; } } else { *msg++ = *fmt++; maxlen -= 1; } } *msg = 0; /* NULL terminate the string */ } return (errstr); } /* Available for backwards compatibility */ char * SDL_GetError(void) { static char errmsg[SDL_ERRBUFIZE]; return ((char *) SDL_GetErrorMsg(errmsg, SDL_ERRBUFIZE)); } void SDL_ClearError(void) { SDL_error *error; error = SDL_GetErrBuf(); error->error = 0; } /* Very common errors go here */ void SDL_Error(SDL_errorcode code) { switch (code) { case SDL_ENOMEM: SDL_SetError("Out of memory"); break; case SDL_EFREAD: SDL_SetError("Error reading from datastream"); break; case SDL_EFWRITE: SDL_SetError("Error writing to datastream"); break; case SDL_EFSEEK: SDL_SetError("Error seeking in datastream"); break; case SDL_UNSUPPORTED: SDL_SetError("That operation is not supported"); break; default: SDL_SetError("Unknown SDL error"); break; } } #ifdef TEST_ERROR int main(int argc, char *argv[]) { char buffer[BUFSIZ + 1]; SDL_SetError("Hi there!"); printf("Error 1: %s\n", SDL_GetError()); SDL_ClearError(); SDL_memset(buffer, '1', BUFSIZ); buffer[BUFSIZ] = 0; SDL_SetError("This is the error: %s (%f)", buffer, 1.0); printf("Error 2: %s\n", SDL_GetError()); exit(0); } #endif /* vi: set ts=4 sw=4 expandtab: */