Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug when freeing a timer (during mutex lock) #79

Closed
SDLBugzilla opened this issue Feb 10, 2021 · 0 comments
Closed

Bug when freeing a timer (during mutex lock) #79

SDLBugzilla opened this issue Feb 10, 2021 · 0 comments

Comments

@SDLBugzilla
Copy link
Collaborator

This bug report was migrated from our old Bugzilla tracker.

Reported in version: 1.2.9
Reported for operating system, platform: Linux, x86

Comments on the original bug report:

On 2006-02-16 11:25:41 +0000, Asfand Yar Qazi wrote:

Hi boys'n'girls (ok, so basically boys...)

I think there may be a bug when exclusive-locking a mutex when freeing a timer caused at the end of my application (I hope my terminology is correct - not too good at concurrency terminology, which is bad, because concurrency is teh futur.)

I'm using the RUDL game library (SDL based game library for Ruby) and when my application window terminates and goes off the screen, process doesn't actually end - (i.e. I don't go back to my shell prompt). I have to manually terminate the process by pressing 'ctrl-c' (i.e. it hasn't crashed.)

This is a fully recreatable bug, it happens ALMOST every time (sometimes the process actually terminates successfully, which is wierd.)

Now, I've gdb'ed it while its in this non-terminated state, and here's some info (actually I used ddd but I've reproduced it using plain terminal mode gdb.) The actual script I run is irrelevant - as long as the script makes a SDL timer, this happens. By the way, this bug also happens exactly the same on SDL-1.2.8 as well as SDL-1.2.9. Amazingly, it DIDN'T happen on a 2.4 kernel with GLIBC 2.2.5 (i.e. before NPTL). Now I'm on the latest stable Gentoo.

Here's a dump of a GDB session where I've noticed some strange stuff going on (note stuff inbetween '<' and '>' is my editing):

$ gdb ../common/root/bin/ruby
GNU gdb 6.4
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) set args test/linktest.rb
(gdb) run
Starting program: /ruby test/linktest.rb
[Thread debugging using libthread_db enabled]
[New Thread -1210422624 (LWP 12988)]
(Init_RUDL())
(Starting video subsystem)
(Starting audio subsystem)
[New Thread -1217238096 (LWP 12991)]
(Starting timer subsystem)
[New Thread -1235706960 (LWP 12993)]
(Starting TTF)
(Reached RUDL_at_exit)
[Thread -1217238096 (zombie) exited]
(Stopping audio subsystem)
(Stopping video subsystem)
(Stopping TTF)
(Quitting the rest of it)
[Thread -1235706960 (zombie) exited]

Program received signal SIGINT, Interrupt.
[Switching to Thread -1210422624 (LWP 12988)]
0xffffe410 in __kernel_vsyscall ()
(gdb) backtrace

0 0xffffe410 in __kernel_vsyscall ()

1 0xb7f2117e in __lll_mutex_lock_wait () from /lib/tls/libpthread.so.0

2 0xb7f1dfc7 in _L_mutex_lock_150 () from /lib/tls/libpthread.so.0

3 0xb7f5bfd4 in ?? () from /lib/ld-linux.so.2

4 0x08152fb0 in ?? ()

5 0x00000001 in ?? ()

6 0xbff575b0 in ?? ()

7 0xb7f51542 in fixup () from /lib/ld-linux.so.2

8 0xb7d39df6 in SDL_mutexP (mutex=0xfffffffc) at SDL_sysmutex.c:133

9 0xb7d3a77e in SDL_RemoveTimer (id=0x826bdd8) at SDL_timer.c:221

10 0xb7d5873d in freeEventTimer (freeMe=0xfffffffc) at rudl_timer.c:46

11 0x08070eaa in rb_gc_call_finalizer_at_exit () at gc.c:1855

12 0x08052e65 in ruby_finalize_1 () at eval.c:1488

13 0x08066b73 in ruby_cleanup (ex=0) at eval.c:1523

14 0x08066c31 in ruby_stop (ex=-4) at eval.c:1554

15 0x08066c7f in ruby_run () at eval.c:1575

16 0x080524e8 in main (argc=-4, argv=0xfffffffc, envp=0xbff578a0) at main.c:46

(gdb) frame 10

10 0xb7d5873d in freeEventTimer (freeMe=0xfffffffc) at rudl_timer.c:46

46 SDL_RemoveTimer(freeMe);
(gdb) l
41 }
42
43 ///////////////////////////////// EVENTTIMER
44 void freeEventTimer(SDL_TimerID freeMe)
45 {
46 SDL_RemoveTimer(freeMe);
47 }
48
49 Uint32 timerCallback(Uint32 interval, void *param)
50 {
(gdb) frame 9

9 0xb7d3a77e in SDL_RemoveTimer (id=0x826bdd8) at SDL_timer.c:221

221 SDL_mutexP(SDL_timer_mutex);
(gdb) l
216 {
217 SDL_TimerID t, prev = NULL;
218 SDL_bool removed;
219
220 removed = SDL_FALSE;
221 SDL_mutexP(SDL_timer_mutex);
222 /* Look for id in the linked list of timers /
223 for (t = SDL_timers; t; prev=t, t = t->next ) {
224 if ( t == id ) {
225 if(prev) {
(gdb) l 210
205 if ( ! SDL_timer_threaded ) {
206 SDL_SetError("Multiple timers require threaded events!");
207 return NULL;
208 }
209 SDL_mutexP(SDL_timer_mutex);
210 t = SDL_AddTimerInternal(interval, callback, param);
211 SDL_mutexV(SDL_timer_mutex);
212 return t;
213 }
214
(gdb)
215 SDL_bool SDL_RemoveTimer(SDL_TimerID id)
216 {
217 SDL_TimerID t, prev = NULL;
218 SDL_bool removed;
219
220 removed = SDL_FALSE;
221 SDL_mutexP(SDL_timer_mutex);
222 /
Look for id in the linked list of timers /
223 for (t = SDL_timers; t; prev=t, t = t->next ) {
224 if ( t == id ) {
(gdb)
225 if(prev) {
226 prev->next = t->next;
227 } else {
228 SDL_timers = t->next;
229 }
230 free(t);
231 --SDL_timer_running;
232 removed = SDL_TRUE;
233 list_changed = SDL_TRUE;
234 break;
(gdb)
235 }
236 }
237 #ifdef DEBUG_TIMERS
238 printf("SDL_RemoveTimer(%08x) = %d num_timers = %d thread = %d\n", (Uint32)id, removed, SDL_timer_running, SDL_ThreadID());
239 #endif
240 SDL_mutexV(SDL_timer_mutex);
241 return removed;
242 }
243
244 /
Old style callback functions are wrapped through this */
(gdb) frame 8

8 0xb7d39df6 in SDL_mutexP (mutex=0xfffffffc) at SDL_sysmutex.c:133

133 if ( pthread_mutex_lock(&mutex->id) < 0 ) {
(gdb) l
128 SDL_SetError("pthread_mutex_lock() failed");
129 retval = -1;
130 }
131 }
132 #else
133 if ( pthread_mutex_lock(&mutex->id) < 0 ) {
134 SDL_SetError("pthread_mutex_lock() failed");
135 retval = -1;
136 }
137 #endif
(gdb) frame 9

9 0xb7d3a77e in SDL_RemoveTimer (id=0x826bdd8) at SDL_timer.c:221

221 SDL_mutexP(SDL_timer_mutex);
(gdb) l
216 {
217 SDL_TimerID t, prev = NULL;
218 SDL_bool removed;
219
220 removed = SDL_FALSE;
221 SDL_mutexP(SDL_timer_mutex);
222 /* Look for id in the linked list of timers */
223 for (t = SDL_timers; t; prev=t, t = t->next ) {
224 if ( t == id ) {
225 if(prev) {
(gdb) print SDL_timer_mutex
$1 = (SDL_mutex *) 0x826a9d8
(gdb) frame 8

8 0xb7d39df6 in SDL_mutexP (mutex=0xfffffffc) at SDL_sysmutex.c:133

133 if ( pthread_mutex_lock(&mutex->id) < 0 ) {
(gdb) l
128 SDL_SetError("pthread_mutex_lock() failed");
129 retval = -1;
130 }
131 }
132 #else
133 if ( pthread_mutex_lock(&mutex->id) < 0 ) {
134 SDL_SetError("pthread_mutex_lock() failed");
135 retval = -1;
136 }
137 #endif
(gdb) print mutex
$2 = (SDL_mutex *) 0xfffffffc
(gdb) quit
The program is running. Exit anyway? (y or n) y

Sorry if that's a bit long, I didn't want to leave anything out.

Ideas?

On 2006-05-07 17:16:53 +0000, Sam Lantinga wrote:

I'd like to get this fixed for SDL 1.2.10 release, if possible.

On 2006-05-09 03:17:04 +0000, Sam Lantinga wrote:

I believe this is now fixed in Subversion. What was happening was a freed mutex was being waited on, after the timer subsystem had already been shut down.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant