acarrillo / sCribble

A collaborative Google Drawing-style sketching program in C
GNU General Public License v3.0
3 stars 1 forks source link

After drawing with rapid motions using pen tool, window mysteriously disappears #1

Closed acarrillo closed 12 years ago

acarrillo commented 12 years ago

The program then has to be force quit, as ^C's do not kill it...

acarrillo commented 12 years ago

Actually, it seems to occur when drawing slowly over time, too. It also seems to occur more frequently with a larger tool_width.

DoronShapiro commented 12 years ago

What happens if you kill it with one of the options that gives you a core dump?

acarrillo commented 12 years ago

Do you know the option for that?

Otherwise, here's Apple's dump. I think it sent a 'hang' signal:

Date/Time:       2012-01-02 16:41:13 -0500
OS Version:      10.6.8 (Build 10K549)
Architecture:    x86_64
Report Version:  7

Command:         sCribble
Path:            ./sCribble
Version:         ??? (???)
Parent:          bash [768]

PID:             8279
Event:           hang
Duration:        7.97s (sampling started after 2 seconds)
Steps:           39 (100ms sampling interval)

Pageins:         0
Pageouts:        0

Process:         sCribble [8279]
Path:            ./sCribble
UID:             501

  Thread 15376      DispatchQueue 1
  User stack:
    39 start + 52 (in sCribble) [0x100001734]
      39 main + 1299 (in sCribble) [0x100002593]
        39 -[NSApplication run] + 395 (in AppKit) [0x7fff8311a68f]
          39 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 155 (in AppKit) [0x7fff83154801]
            39 _DPSNextEvent + 1191 (in AppKit) [0x7fff83155095]
              39 AEProcessAppleEvent + 48 (in HIToolbox) [0x7fff89729619]
                39 aeProcessAppleEvent + 210 (in AE) [0x7fff808e412b]
                  39 dispatchEventAndSendReply(AEDesc const*, AEDesc*) + 32 (in AE) [0x7fff808e4224]
                    39 aeDispatchAppleEvent(AEDesc const*, AEDesc*, unsigned int, unsigned char*) + 162 (in AE) [0x7fff808e432b]
                      39 _NSAppleEventManagerGenericHandler + 114 (in Foundation) [0x7fff859b2f06]
                        39 -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:] + 360 (in Foundation) [0x7fff859b30d6]
                          39 -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] + 77 (in AppKit) [0x7fff8324ffd9]
                            39 -[NSApplication(NSAppleEventHandling) _handleAEOpen:] + 219 (in AppKit) [0x7fff8325035d]
                              39 -[NSApplication _sendFinishLaunchingNotification] + 66 (in AppKit) [0x7fff8318537f]
                                39 -[NSApplication _postDidFinishNotification] + 100 (in AppKit) [0x7fff8318544a]
                                  39 -[NSNotificationCenter postNotificationName:object:userInfo:] + 101 (in Foundation) [0x7fff8597ba36]
                                    39 _CFXNotificationPostNotification + 200 (in CoreFoundation) [0x7fff84cb0548]
                                      39 __CFXNotificationPost + 1008 (in CoreFoundation) [0x7fff84cc3fd0]
                                        39 _nsnote_callback + 167 (in Foundation) [0x7fff85984ad5]
                                          39 -[SDLMain applicationDidFinishLaunching:] + 48 (in sCribble) [0x100001f40]
                                            39 SDL_main + 49 (in sCribble) [0x100001d43]
                                              39 updateScreen + 198 (in sCribble) [0x100001ca0]
                                                39 drawFilledRect + 147 (in sCribble) [0x100001a90]
                                                  39 ??? [0x10024b2f0]
                                                    39 _sigtramp + 26 (in libSystem.B.dylib) [0x7fff82fb01ba]
                                                      39 SDL_Parachute + 23 (in libSDL-1.2.0.dylib) [0x1000087d7]
                                                        39 SDL_Quit + 14 (in libSDL-1.2.0.dylib) [0x100007d6e]
                                                          39 SDL_QuitSubSystem + 88 (in libSDL-1.2.0.dylib) [0x100007ce8]
                                                            39 SDL_VideoQuit + 139 (in libSDL-1.2.0.dylib) [0x10002f7bb]
                                                              39 ??? (in sCribble + 18446744069414584320) [0x0]
  Kernel stack:
    35 lo_alltraps + 298 [0x2a18da]
      35 user_trap + 851 [0x2ab8ef]
        34 exception_triage + 222 [0x21be55]
          32 exception_deliver + 490 [0x21bb23]
            32 mach_exception_raise + 179 [0x23df2b]
              32 mach_msg_rpc_from_kernel_proper + 39 [0x21e3d2]
                25 mach_msg_rpc_from_kernel_body + 384 [0x21e2d7]
                  24 ipc_mqueue_receive + 101 [0x211dd0]
                    24 thread_block + 33 [0x227654]
                      19 thread_block_reason + 331 [0x2275c6]
                        19 thread_dispatch + 1966 [0x227327]
                          19 machine_switch_context + 659 [0x2a9adb]
                      5 thread_block_reason + 395 [0x227606]
                        5 ml_set_interrupts_enabled + 47 [0x2a45e3]
                  1 ipc_mqueue_receive + 57 [0x211da4]
                    1 ipc_mqueue_receive_on_thread + 21 [0x2119c5]
                      1 ml_set_interrupts_enabled + 46 [0x2a45e2]
                4 mach_msg_rpc_from_kernel_body + 205 [0x21e224]
                  4 ipc_kmsg_send + 420 [0x210bc1]
                    2 ipc_mqueue_send + 84 [0x21128a]
                      2 ml_set_interrupts_enabled + 47 [0x2a45e3]
                    2 ipc_mqueue_send + 423 [0x2113dd]
                      2 ipc_mqueue_post + 545 [0x21121c]
                        2 ml_set_interrupts_enabled + 47 [0x2a45e3]
                1 mach_msg_rpc_from_kernel_body + 444 [0x21e313]
                  1 ipc_object_release + 26 [0x21212b]
                    1 lck_mtx_lock + 119 [0x29a527]
                1 mach_msg_rpc_from_kernel_body + 41 [0x21e180]
                  1 ipc_kmsg_get_from_kernel + 181 [0x2107ec]
                    1 _enable_preemption + 17 [0x29aca1]
                      1 kernel_preempt_check + 70 [0x2aac45]
                        1 ml_set_interrupts_enabled + 47 [0x2a45e3]
                1 mach_msg_rpc_from_kernel_body + 247 [0x21e24e]
                  1 lck_mtx_lock + 9 [0x29a4b9]
          1 exception_deliver + 146 [0x21b9cb]
            1 lck_mtx_unlock_darwin10 + 149 [0x29a9f5]
          1 exception_deliver + 419 [0x21badc]
        1 exception_triage + 168 [0x21be1f]
          1 exception_deliver + 104 [0x21b9a1]
            1 lck_mtx_unlock_darwin10 + 6 [0x29a966]
    3 lo_alltraps + 284 [0x2a18cc]
    1 lo_alltraps + 454 [0x2a1976]
      1 i386_astintr + 47 [0x2aacb4]
        1 ast_taken + 247 [0x219432]
          1 bsd_ast + 13 [0x48fba7]
            1 get_bsdthread_info + 1 [0x235e2c]

  Thread 15379      DispatchQueue 2
  User stack:
    39 start_wqthread + 13 (in libSystem.B.dylib) [0x7fff82f69aa5]
      39 _pthread_wqthread + 353 (in libSystem.B.dylib) [0x7fff82f69c08]
        39 _dispatch_worker_thread2 + 252 (in libSystem.B.dylib) [0x7fff82f6a2de]
          39 _dispatch_queue_invoke + 185 (in libSystem.B.dylib) [0x7fff82f6a7b4]
            39 kevent + 10 (in libSystem.B.dylib) [0x7fff82f68c0a]
  Kernel stack:
    39 kevent + 97 [0x47a699]

  Binary Images:
         0x100000000 -        0x100002ff7  sCribble ??? (???) <24057434-6A37-8B69-C342-69D0979C911B> /Users/Ginkgo/Documents/Cribble/./sCribble
         0x100006000 -        0x10006dfff  libSDL-1.2.0.dylib ??? (???) <FB0F523B-97A9-3689-A8A0-1A9FD4FFF596> /opt/local/lib/libSDL-1.2.0.dylib
      0x7fff808e1000 -     0x7fff8091cfff  com.apple.AE 496.5 (496.5) <208DF391-4DE6-81ED-C697-14A2930D1BC6> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE
      0x7fff82f4f000 -     0x7fff83110fef  libSystem.B.dylib ??? (???) <9AB4F1D1-89DC-0E8A-DC8E-A4FE4D69DB69> /usr/lib/libSystem.B.dylib
      0x7fff83111000 -     0x7fff83b0bff7  com.apple.AppKit 6.6.8 (1038.36) <4CFBE04C-8FB3-B0EA-8DDB-7E7D10E9D251> /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
      0x7fff84c6b000 -     0x7fff84de2fe7  com.apple.CoreFoundation 6.6.6 (550.44) <BB4E5158-E47A-39D3-2561-96CB49FA82D4> /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
      0x7fff85974000 -     0x7fff85bf6fff  com.apple.Foundation 6.6.8 (751.63) <E10E4DB4-9D5E-54A8-3FB6-2A82426066E4> /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
      0x7fff896f5000 -     0x7fff899f3fff  com.apple.HIToolbox 1.6.5 (???) <AD1C18F6-51CB-7E39-35DD-F16B1EB978A8> /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox
acarrillo commented 12 years ago

Hooray for gdb! Caught this:


Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x0000000115313b54
0x00000001000019f9 in drawPixel (x=341, y=-640, color=-65536) at src/graphics.c:10
10      *pixel = color;

Not sure what to do about this, but at least we know it's a memory issue now...

acarrillo commented 12 years ago

Also look at the value of the color field. Is that not an integer overflow?

Likewise, the y coordinate is skewed. -640 is impossible...

vzeddie commented 12 years ago

I sent an email:

"I think I figured out why the screen mysteriously disappears. It seems that if you drag the pen out of the screen multiple times, it will disappear. It will continue to work unless you draw outside of the screen multiple times. Maybe we should open up a full screen instead? I guess when xcor and ycor are sent and they aren't in the screen, it sends -1 or something to the function causing the screen to exit."

acarrillo commented 12 years ago

@azureity I think you may be on to something, but check this out:

If you pull the latest code, you can change the width of the tool in line 30 of src/init.c. If you set it to something like 100, then move the cursor around for a while, you will see the window disappear very quickly, without ever leaving the boundaries. However, when I did it that time, gdb caught this:

INPUT.C -- xcor:210 ycor:199
INPUT.C -- xcor:253 ycor:86
INPUT.C -- xcor:282 ycor:54
INPUT.C -- xcor:308 ycor:43

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x000000011530fe08
0x00000001000019e3 in drawPixel (x=258, y=-4480, color=-65536) at src/graphics.c:10
10      *pixel = color;

Printing out the coordinates of the cursor proves that it was still inside the window.

So now the y value was -5760. The color was still crazy. If there really is a memory access problem, though, then it is possible the values of y and color are garbage because it is the wrong memory.

Also, if the values of xcor and ycor were -1, it simply wouldn't draw anything. I use an xcor value of -1 a signal that there has been no penning to the drawing since the last iteration (here).

vzeddie commented 12 years ago

Okay. So I changed the pen tool size to 100 and it seems to work when I draw horizontally. Horizontal drawing can exceed the screen's limits but when I go past the limit vertically (passing the screen's upward or downward boundaries), it exits. I just tried it with pen size 5 (original size) and it only seems that if the pen exceeds the vertical boundaries does the "mysterious" exiting happen. Something is right with the xcor management but it's not being done the same with the ycor.

vzeddie commented 12 years ago

A 'segfault' occurs when the pen goes past the vertical boundaries. It doesn't when it goes past the horizontal.

acarrillo commented 12 years ago

Also, I see a red line through the center of the screen. Errr...Is that supposed to happen?

Yeah. That was just me testing the line drawing function at https://github.com/acarrillo/Cribble/blob/master/src/graphics.c#L58

vzeddie commented 12 years ago

Got it.

In init.c, somehow, in line 49 (Detected mouse motion), when ycor goes below 0 or above 475 (the screen's bottom edge), it must stop.

vzeddie commented 12 years ago

WHOOOO! I fixed it!

if(mouse.ycor > 475 || mouse.ycor <= 2){ mouse.xcor = -1; mouse.ycor = -1; }

added to input.c around line 52 (After mouse.ycor = event.button.y;). It's hardcoded to the screen's size though. If there is a variable for the screen's height, that'd be nice. I'm currently learning how to work git so I'm going to try to commit this change. If it doesn't work, then it's here. Add "|| mouse.xcor > 475 || mouse.xcor < 2" if you want.

DoronShapiro commented 12 years ago

That may fix it. If not, it seems as though we're drawing on the canvas through a rather roundabout process... aren't functions to draw lines already defined in SDL? http://wiki.libsdl.org/moin.cgi/SDL_RenderDrawLine

vzeddie commented 12 years ago

My fix doesn't work when the pen size is too large as the pen will exceed the vertical boundaries before the mouse.ycor does. There must be some sort of algorithm that can fix this. Something that will modify the if statement to change according to the pen size. Or we can find the reason why the horizontal boundaries don't work this way and modify the vertical to work like that.

acarrillo commented 12 years ago

Confirmed: commit cb50f3586 fixes this.

@DoronShapiro what's an SDL_Renderer? It's not in my documentation, which I downloaded from here. Is that because Renderers are in SDL 1.3, and I am running SDL 1.2?


Ginkgo ~ $ port info libsdl
libsdl @1.2.14, Revision 8 (devel, multimedia)
vzeddie commented 12 years ago

Warning: This only works for pen size 5 as of now.

DoronShapiro commented 12 years ago

@acarrillo good point, that was for the beta version. How's this? http://www.libsdl.org/cgi/docwiki.cgi/SDL_FillRect Data structure: http://www.libsdl.org/cgi/docwiki.cgi/SDL_Rect

acarrillo commented 12 years ago

Oh yeah. That works too :P

acarrillo commented 12 years ago

If there is a variable for the screen's height, that'd be nice.

@azureity screen->width and screen->height are the values you are looking for. See http://www.libsdl.org/cgi/docwiki.cgi/SDL_Surface

I now see why this was fundamentally a memory issue. If the x or y value was out of range, it would then try to change the value of an index of the screen->pixel that was inexistant.

acarrillo commented 12 years ago

Also, I think this is now fixed for large-sized tools as well. Can anyone verify?

vzeddie commented 12 years ago

That's odd...the x values work fine. It's just the y values that cause a memory issue when it's out of range.

acarrillo commented 12 years ago

I think it is because changes in the y value have a greater effect on the pointer arithmetic. Because the screen->pixel array, which describes a two-dimensional field, is linear, rows make huge jumps...e.g. row one might start at index 0, row two at index 640, row three at 1280, etc.

Therefore, incrementing x by one will only yield small changes, e.g. from the 5th index to the 6th. But incrementing y will result in jumps from the 0th index to the 640th.

Here's what's happening to the y value in line 17 of graphics.c:

        ytimesw = (yi+y)*screen->pitch/4;

It is getting multiplied by screen "pitch", which describes how many bytes each row takes.

vzeddie commented 12 years ago

Oh. I understand.

I also tested out the new files (How do I update my repository from my terminal? I downloaded the .zip file manually). It seems to work only sometimes. We are no longer getting segfaults from crossing the boundaries but it is using both dots and lines. It makes for some odd looking drawings. If I move it slowly, it still works fine but when I rapidly draw, it draws thin lines sometimes, sometimes it's thick lines, other times it's just dots like before.

vzeddie commented 12 years ago

I was playing around a bit and it seems to me that when I rapidly draw diagonally it's purely dots that I get. But this only happens when I draw from SW - NE. If I draw SE - NW, it draws a lot better (They're all dots, it's just that the dots seem to be drawn more often when moving SE - NW). If I draw horizontally or vertically, I get sporadic lines. Also, the lines are drawn very thinly while the dots are drawn thickly. It makes for an odd combination.

This becomes apparent if you set pen size to 1.

(This is using pen size 5)

acarrillo commented 12 years ago

I created issue #3 for this. Indeed, line drawing is not yet functional.