Hi,

I'm chasing a bug in GWorkspace which casues a hang when multiple file operation happen.

Current GWorkspace works when a single operation is performed (e.g. just copy a file) on:
1) Linux/gcc/gcc runtime
2) OpenBSD/gcc/gcc runtime
3) NetBSD/clang/libobjc2

After weeks of "chasing" I think I found the bug: A method in Operation.m tries to determine the best position for the progress panel, returning NSZeroRect if no other operaiton is running, a relative position is one is running. This method consistently returns an array out of bounds exception, being written badly. I rewrote the method with the attached patch, it is 99% equivalent and should, at least, be equivalent in the case of NO other operation running, that is returning NSZeroRect.
I attach the patch.

The patch seems to work with one or more operations on both gcc computers.
However on NetBSD with clang, on copy I get a hang even with at the first copy operation! Why? nothing meaningful should change. Is my new code buggy? Or does it trigger some runtime bug?


I tried to debug with gdb, but in that case I get a hang at a later stage: instead of haning immediately when an operation should start, it completes (panel comes up, progress, ends) and hangs later on termination with this trace:

#1  0xbafe51e3 in write () from /usr/lib/libpthread.so.1
#2 0xbb30a8a2 in -[GSMessageHandle receivedEvent:type:extra:forMode:] (self=0xb7ff9388, _cmd=<optimized out>, data=<optimized out>, type=<optimized out>, extra=0xd,
    mode=<optimized out>) at NSMessagePort.m:951
#3  0xbb34c203 in -[GSRunLoopCtxt pollUntil:within:] (self=0xb8cff2e8,
    _cmd=<optimized out>, milliseconds=Cannot access memory at address 0x0
) at GSRunLoopCtxt.m:598
#4 0xbb29c502 in -[NSRunLoop acceptInputForMode:beforeDate:] (self=0xbb4b4960,
    _cmd=<optimized out>, mode=<optimized out>, limit_date=<optimized out>)
    at NSRunLoop.m:1219
#5  0xbb29ca49 in -[NSRunLoop runMode:beforeDate:] (self=0xb8af9828,
_cmd=<optimized out>, mode=<optimized out>, date=<optimized out>) at NSRunLoop.m:1290 #6 0xbb30bdbc in -[GSMessageHandle sendMessage:beforeDate:] (self=0xb7ff9388,
    _cmd=<optimized out>, components=<optimized out>, when=<optimized out>)
    at NSMessagePort.m:1034
#7 0xbb30e6a7 in -[NSMessagePort sendBeforeDate:msgid:components:from:reserved:] ( self=<optimized out>, _cmd=0xbb4b1fa8, when=<optimized out>, msgId=<optimized out>, components=0xb7109368, receivingPort=<optimized out>, length=<optimized out>)
    at NSMessagePort.m:1966
#8 0xbb1f0f13 in -[NSConnection(Private) _sendOutRmc:type:] (self=0xb7d86648,
    _cmd=0xbb4b2008, c=0xb71431d8, msgid=7) at NSConnection.m:3448
#9 0xbb1f2f2d in -[NSConnection(Private) _release_target:count:] (self=0xb7d86648,
    _cmd=0xbb4b2010, target=1, number=1) at NSConnection.m:3666
#10 0xbb1f4ecd in -[NSConnection(Private) removeProxy:] (self=0xb7d86648,
    _cmd=0xbb4b81e0, aProxy=0xb7dadb88) at NSConnection.m:3873
#11 0xbb21c3e1 in -[NSDistantObject(GNUstepExtensions) finalize] (self=<optimized out>,
    _cmd=0xbb4b8220) at NSDistantObject.m:846
#12 0xbb21b515 in -[NSDistantObject dealloc] (self=0xb7dadb88, _cmd=0xb7dadb88)
    at NSDistantObject.m:465
#13 0xbb29825d in -[NSProxy release] (self=0xb7dadb88, _cmd=0x811c2d0) at NSProxy.m:464 #14 0x0808071a in -[GWorkspace applicationShouldTerminate:] (self=0x811c690,
    _cmd=0xbb9b4218, app=0xb8c0bc58) at GWorkspace.m:645
#15 0xbb70bc64 in -[NSApplication terminate:] (self=0xb8c0bc58, _cmd=0x811c4b8,
    sender=0xb7fc3e28) at NSApplication.m:3462
#16 0xbb709603 in -[NSApplication sendAction:to:from:] (self=0xb8c0bc58, _cmd=0xbb9ecb38, aSelector=0x811c4b8, aTarget=0x0, sender=<optimized out>) at NSApplication.m:2230
#17 0xbb7b83a5 in -[NSMenu performActionForItemAtIndex:] (self=0xb8c0bc58,
    _cmd=0xbb9ee308, index=<optimized out>) at NSMenu.m:1331
#18 0xbb7c00a0 in -[NSMenuView _trackWithEvent:startingMenuView:] (self=0xb8aeba08,
    _cmd=0x0, event=<optimized out>, mainWindowMenuView=<optimized out>)
    at NSMenuView.m:1916
#19 0xbb7c0386 in -[NSMenuView trackWithEvent:] (self=0xb8aeba08, _cmd=0xbb9ee4c8,
    event=<optimized out>) at NSMenuView.m:1948
#20 0xbb7c0500 in -[NSMenuView mouseDown:] (self=0xb8aeba08, _cmd=0x3fb99999,
    theEvent=<optimized out>) at NSMenuView.m:1988
#21 0xbb882081 in -[NSWindow sendEvent:] (self=<optimized out>, _cmd=0x41e00000,
    theEvent=<optimized out>) at NSWindow.m:3898
#22 0xbb709216 in -[NSApplication sendEvent:] (self=<optimized out>, _cmd=0xbb9b4358,
    theEvent=<optimized out>) at NSApplication.m:2107
#23 0xbb708187 in -[NSApplication run] (self=<optimized out>, _cmd=0x81160b8)
    at NSApplication.m:1562
#24 0x0807b234 in gnustep_base_user_main (argc=1, argv=0xbfbfe8b4, env=0xbfbfe8bc)
    at main.m:38
#25 0x0807b095 in ___start ()
#26 0x0807af68 in _start ()




Any ideas?? I'm really puzzled!

Riccardo
Index: Operation/Operation.m
===================================================================
--- Operation/Operation.m       (revision 38258)
+++ Operation/Operation.m       (working copy)
@@ -361,7 +361,9 @@
 {
   NSRect scr = [[NSScreen mainScreen] visibleFrame];
   NSRect wrect = NSZeroRect;
-  NSUInteger i;  
+  NSUInteger i;
+  NSWindow *winOp;
+  NSRect wr = NSZeroRect;
 
   #define WMARGIN 50
   #define WSHIFT 50
@@ -371,28 +373,32 @@
   scr.size.width -= (WMARGIN * 2);
   scr.size.height -= (WMARGIN * 2);
 
-  for (i = [fileOperations count]; i > 0; i--) {
-    FileOpInfo *op = [fileOperations objectAtIndex: i];
+  NSLog(@"operations: %@", fileOperations);
 
-    if ([op win]) {
-      NSRect wr = [op winRect];
+  for (i = 0; i < [fileOperations count]; i++)
+    {
+      FileOpInfo *op = [fileOperations objectAtIndex: i];
 
-      if (NSEqualRects(wr, NSZeroRect) == NO) {
-        wrect = NSMakeRect(wr.origin.x + WSHIFT, 
-                           wr.origin.y - wr.size.height - WSHIFT,
-                           wr.size.width,
-                           wr.size.height);
+      if ([op win])
+        wr = [op winRect];
+    }
 
-        if (NSContainsRect(scr, wrect) == NO) {
+  if (NSEqualRects(wr, NSZeroRect) == NO)
+    {
+      wrect = NSMakeRect(wr.origin.x + WSHIFT, 
+                         wr.origin.y - wr.size.height - WSHIFT,
+                         wr.size.width,
+                         wr.size.height);
+      
+      if (NSContainsRect(scr, wrect) == NO)
+        {
           wrect = NSMakeRect(scr.origin.x, 
                              scr.size.height - wr.size.height,
                              wr.size.width, 
                              wr.size.height);
-          break;
         }
-      }
     }
-  }
+  NSLog(@"wrect  %f %f %f %f", wrect.origin.x, wrect.origin.y, 
wrect.size.width, wrect.size.height);
 
   return wrect;
 }
_______________________________________________
Discuss-gnustep mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep

Reply via email to