GNOME Bugzilla – Bug 740634
Color picker crashes when there are multiple monitors
Last modified: 2017-04-30 19:28:07 UTC
The problem happens when you do the following: 1. Start GIMP 2. Load an image. (I have tried both jpg and png images. I get the same result.) 3. Click on the Foreground/Background color tool, to open the Color Dialog. 4. Click on eyedropper tool icon, within the Color dialog. (The tool tip for the eyedropper will tell you: "Click the eyedropper, then click a color anywhere on your screen to select that color.") 5. Click anywhere within your loaded picture. 6. You should get the following message: "GNU Image Manipulation Program has stopped working". After looking at the Problem Details, I noticed the following items: "Fault Module Name: libpixman-1-0.dll" and "Exception Code: c0000005". I did lookup that item and notice others reporting the same issue on Win7x64, which is what I am using. However, I did not see anyone with a solution or fix. Nor did I see anyone having reported the issue. I can recreate the error over and over again, consistently. I would gladly pass along any other information or screenshots, if they are needed.
Can't reproduce this on Windows 7 64 Bit - works flawlessly on a loaded image, a new image or anywhere on my desktop.
Something I noticed after submitting this bug report, there are 2 different tools that ultimately should do the same thing. But for me only one of them works and the other throws the above error. -- Color Picker Tool (located in the main "Toolbox/Tool Options" dialog) works and works as I would expect. -- eyedropper (located in the "color selection" dialog) causes the above error.
I tried this with the eyedropper from the color selection dialog and couldn't reproduce it.
I've got this same issue. May have something to do with the graphics driver. I have a laptop with a 3 monitor setup using a standard docking station & a USB 3.0 Port Replicator. I have 2 monitors connected to the standard docking station and one connected to the port replicator. If I perform this task on the 3rd monitor (using the port replicator), this operation works but propagates black to the field I'm trying to set the color regardless of the color I select. If I do this to one of the monitors connected to the docking station, it crashes the program as stated in the initial report. I have video screenshots of this issue, but am a new user and not entirely certain that I can upload them.
The initial report didn't mention any special monitor setup. tony, what would be the screen dimensions of all monitors combined, and where is the one located where picking triggers the crash? (e.g. "three monitors of 1024x768 each, broken behavior is on the rightmost monitor starting at x-position 2048+")
Hi Tony, That is very interesting, I had never really made that connection, till you mentioned it. I also have a 3 monitor setup. However, I have a desktop machine. 2 of my monitors are plugged directly into the video card and the 3rd uses a USB video extender. Each monitor is a different size, but the combined desktop size is 4880x1080. I did like what you mentioned and tried this on each monitor. To do this, I switched GIMP to use "Single-Window Mode" (as found under the "Windows" menu option). Once the GIMP was in Single-Window Mode, I put the window in each monitor and tried as explained above. In the 2 screens attached directly to the Video Card, GIMP threw the error as mentioned above ("GNU Image Manipulation Program has stopped working", Fault Module Name: libpixman-1-0.dll, Exception Code: c0000005). However, GIMP did not throw any errors when trying this on my 3rd monitor (the USB connected monitor). But with that said, it would NOT select the color I clicked on with the Eyedropper. The color selection stayed as it was before click ion the Eyedropper. In my typical usage, I have been using GIMP with the "Single-Window Mode" off. I have attached a screen shot of what my desktop looks like with "Single-Window Mode" off.
Created attachment 296789 [details] Screenshot of Window layout
Can you describe which monitor in the window layout corresponds to which one from your description in comment #6?
Oh sure.. that would probably help. Screen 1 and 2 are connected directly to a Video Card. The Video Card specs are: - NVIDIA GeForce GTS 250 (BFG Tech) - 1 Gb DDR3 RAM - PCI-Express x16 - Driver Version: GeForce 340.52 (Released: 7/29/2014) Screen 3 is connected to a USB video extender. There is the specs on that: http://www.newegg.com/Product/Product.aspx?Item=N82E16815101001 Encase it helps the rest of my machine is: Dell T5500 - Dual Xeon E5506 @ 2.13GHz (Quad Core / 8 Cores Combined) - 6 Gb DDR3 RAM (Triple Channel) - 120 Gb SSD Harddrive (Kingston) - 2x500 Gb Harddrive (Western Digital)
Same issue here. Crashes only with the color picker within the color dialog; the top-level color picker tool works fine. FWIW, I have a dual-monitor setup: AMD FirePro W4100 driving two monitors (old Dell 20", new Dell 27") connected directly to the video card. I'm running Win7 Pro, Core i5-2500K @3.3GHz, 8GB RAM. If there's any data I can collect to help with this I'm happy to help.
This happens to me too. Windows 8.1, 3 monitors, 2 GPUs (GeForce GTX 560 Ti + GeForce GT 610): Unhandled exception at 0x0000000000B5CE00 (libpixman-1-0.dll) in gimp-2.8.exe: 0xC0000005: Access violation reading location 0x000000002AC44F44. Call stack from main thread, for whatever it's worth: > libpixman-1-0.dll!0000000000b5ce00() Unknown libpixman-1-0.dll!0000000000b5cf95() Unknown libpixman-1-0.dll!0000000000ad2641() Unknown libcairo-2.dll!0000000068de02bd() Unknown libcairo-2.dll!0000000068e165f2() Unknown libcairo-2.dll!0000000068e16a7e() Unknown libcairo-2.dll!0000000068e16b6a() Unknown libcairo-2.dll!0000000068dd5b61() Unknown libcairo-2.dll!0000000068de5d61() Unknown libcairo-2.dll!0000000068e19b10() Unknown libcairo-2.dll!0000000068ddd322() Unknown libcairo-2.dll!0000000068dd0809() Unknown libgimpwidgets-2.0-0.dll!0000000063aa1e13() Unknown libgimpwidgets-2.0-0.dll!0000000063aa20e3() Unknown libgtk-win32-2.0-0.dll!00000000618482bb() Unknown libgobject-2.0-0.dll!0000000000a85f8f() Unknown libgobject-2.0-0.dll!0000000000a96d23() Unknown libgobject-2.0-0.dll!0000000000a9da68() Unknown libgobject-2.0-0.dll!0000000000a9dea8() Unknown libgtk-win32-2.0-0.dll!0000000061959d92() Unknown libgtk-win32-2.0-0.dll!0000000061846901() Unknown libgtk-win32-2.0-0.dll!0000000061846cbb() Unknown libgdk-win32-2.0-0.dll!000000006c37b85b() Unknown libglib-2.0-0.dll!00000000685f0ee3() Unknown libglib-2.0-0.dll!00000000685f10d8() Unknown libglib-2.0-0.dll!00000000685f1515() Unknown gimp-2.8.exe!00000000004017f7() Unknown gimp-2.8.exe!000000000071f65a() Unknown gimp-2.8.exe!00000000004013ce() Unknown gimp-2.8.exe!00000000004014c8() Unknown kernel32.dll!00007fff3fba13d2() Unknown ntdll.dll!00007fff4010e954() Unknown Instructions about the crash point, if it'll help track it down: 0000000000B5CDBC jg 0000000000B5CDA1 0000000000B5CDBE sub edx,10h 0000000000B5CDC1 mov r8d,edx 0000000000B5CDC4 and edx,0Fh 0000000000B5CDC7 shr r8d,4 0000000000B5CDCB add r8,1 0000000000B5CDCF shl r8,4 0000000000B5CDD3 add rax,r8 0000000000B5CDD6 add rcx,r8 0000000000B5CDD9 cmp edx,3 0000000000B5CDDC jle 0000000000B5CE1E 0000000000B5CDDE sub edx,4 0000000000B5CDE1 mov r13d,edx 0000000000B5CDE4 shr r13d,2 0000000000B5CDE8 mov r8d,r13d 0000000000B5CDEB lea r10,[r8*4+4] 0000000000B5CDF3 xor r8d,r8d 0000000000B5CDF6 nop word ptr cs:[rax+rax] 0000000000B5CE00 mov r9d,dword ptr [rcx+r8] <-- EIP is here 0000000000B5CE04 mov dword ptr [rax+r8],r9d 0000000000B5CE08 add r8,4 0000000000B5CE0C cmp r8,r10 0000000000B5CE0F jne 0000000000B5CE00 0000000000B5CE11 neg r13d 0000000000B5CE14 add rcx,r8 0000000000B5CE17 add rax,r8 0000000000B5CE1A lea edx,[rdx+r13*4] 0000000000B5CE1E cmp edx,1 0000000000B5CE21 jle 0000000000B5CE29 0000000000B5CE23 movzx edx,word ptr [rcx] 0000000000B5CE26 mov word ptr [rax],dx 0000000000B5CE29 sub r11d,1 0000000000B5CE2D mov rax,rdi 0000000000B5CE30 mov rcx,rsi 0000000000B5CE33 test r11d,r11d 0000000000B5CE36 jne 0000000000B5CCB5 0000000000B5CE3C mov eax,1 0000000000B5CE41 pop rbx Registers: RAX = 00000000073CE810 RBX = 0000000000000004 RCX = 000000002AC44F44 RDX = 0000000000000000 RSI = 000000002AC492C4 RDI = 00000000073CE814 R8 = 0000000000000000 R9 = 0000000000000004 R10 = 0000000000000004 R11 = 0000000000000001 R12 = 0000000000004380 R13 = 0000000000000000 R14 = 000000000023E610 R15 = 0000000000000000 RIP = 0000000000B5CE00 RSP = 000000000023E478 RBP = 0000000000000004 EFL = 00010244 OV = 0 UP = 0 EI = 1 PL = 0 ZR = 1 AC = 0 PE = 1 CY = 0 0x000000002ac44f44 = 00000000 Hopefully I can attach the minidump to this bug somehow... let me see...
Created attachment 300103 [details] Minidump of GIMP 2.8 eyedropper crash Saved from VS2013... I have a 46MB "mini"dump with heap too, if you want it.
There is another report for this bug where I provided a stack strace with line numbers instead of offsets and a description on how to reproduce the bug (multi-monitor setups seem to be the problem): https://bugzilla.gnome.org/show_bug.cgi?id=746393
Occurring here on 3 monitor setup, Windows 8.1 64-bit, Gimp 2.8.14
Problem Event Name: APPCRASH Application Name: gimp-2.8.exe Application Version: 2.8.14.0 Application Timestamp: 00000000 Fault Module Name: libpixman-1-0.dll Fault Module Version: 0.0.0.0 Fault Module Timestamp: a338a330 Exception Code: c0000005 Exception Offset: 000000000008ce00 OS Version: 6.1.7601.2.1.0.256.1 Locale ID: 1033 Additional Information 1: db55 Additional Information 2: db55b1b083844b868194578e69c6c55f Additional Information 3: 1e17 Additional Information 4: 1e1709d8b27a9c2eaad4cd27c2c92999 Windows 7 Ultimate 64bit 3 monitors arranged right to left on desktop (3-2-1) Crash only occurs when I use (try to select a pixel with) the eyedropper on display 3. On the other two monitors there is no crash, no effect, nothing.
(In reply to Paul King from comment #15) > Problem Event Name: APPCRASH > Application Name: gimp-2.8.exe > Application Version: 2.8.14.0 > Application Timestamp: 00000000 > Fault Module Name: libpixman-1-0.dll > Fault Module Version: 0.0.0.0 > Fault Module Timestamp: a338a330 > Exception Code: c0000005 > Exception Offset: 000000000008ce00 > OS Version: 6.1.7601.2.1.0.256.1 > Locale ID: 1033 > Additional Information 1: db55 > Additional Information 2: db55b1b083844b868194578e69c6c55f > Additional Information 3: 1e17 > Additional Information 4: 1e1709d8b27a9c2eaad4cd27c2c92999 > > Windows 7 Ultimate 64bit > 3 monitors arranged right to left on desktop (3-2-1) > Crash only occurs when I use (try to select a pixel with) the eyedropper on > display 3. > On the other two monitors there is no crash, no effect, nothing. Just to see if it is a hardware thing, I installed Gimp 2 on a Ubuntu VM I have running in VMware Workstation on top of my Win 7 Ult system, spanned the desktop across all three monitors, and retested: no problem whatsoever.
We are at 2.8.16 now, btw.
I can confirm this also. Setup: - GIMP 2.8.16 - Windows 7 x64 - AMD Radeon R9 R270 2GB - AMD driver version: 14.501.1003.0 and 15.300.1025.0 (tried with older version, and then tried with latest AMD driver version) - 3 monitor setup (using 2 DVI and 1 DisplayPort) - Monitors identity in display setting panel show monitor 1 (rightmost) is DP, monitor 2 (center) and 3 (leftmost) are DVI. GIMP crash if I pick a color on any of the 2nd and 3rd monitors (DVI), fine if I pick a color on the 1st monitor (DP). If I have the image split between a DVI monitor and the DP monitor, by dragging the windows to span 2 monitors, it crash if I select a pixel that is not on the 1st monitor, but fine if I select another pixel in the same image that is on the 1st monitor (DP). Regards, Eric
This is still happening on 1/26/16 after I installed a second monitor. Gimp 2.8.16, Windows 10 x64, GTX 970, i5 4670k.
*** Bug 746393 has been marked as a duplicate of this bug. ***
*** Bug 752729 has been marked as a duplicate of this bug. ***
A few months ago (2015-05-06), I compiled gimp, babl, cairo, gegl and pixman from their respective git master and this was the stacktrace I got: #0 sse2_blt at pixman-sse2.c line 4791 #1 sse2_blt at pixman-sse2.c line 4822 #2 sse2_composite_copy_area at pixman-sse2.c line 4815 #3 pixman_image_composite32 at pixman.c line 709 #4 composite_boxes at cairo-image-compositor.c line 538 #5 composite_aligned_boxes at cairo-spans-compositor.c line 683 #6 clip_and_composite_boxes at cairo-spans-compositor.c line 882 #7 clip_and_composite_boxes at cairo-spans-compositor.c line 901 #8 _cairo_spans_compositor_paint at cairo-spans-compositor.c line 983 #9 _cairo_compositor_paint at cairo-compositor.c line 65 #10 _cairo_image_surface_paint at cairo-image-surface.c line 927 #11 _cairo_surface_paint at cairo-surface.c line 2117 #12 _cairo_gstate_paint at cairo-gstate.c line 1067 #13 cairo_paint at cairo.c line 2003 #14 gimp_pick_button_pick at gimppickbutton.c line 385 #15 gimp_pick_button_mouse_release at gimppickbutton.c line 338 #16 ?? from /mingw64/bin/libgtk-win32-2.0-0.dll #17 ?? from /mingw64/bin/libgobject-2.0-0.dll #18 ?? from /mingw64/bin/libgobject-2.0-0.dll #19 ?? from /mingw64/bin/libgobject-2.0-0.dll #20 ?? from /mingw64/bin/libgobject-2.0-0.dll #21 ?? from /mingw64/bin/libgtk-win32-2.0-0.dll #22 ?? from /mingw64/bin/libgtk-win32-2.0-0.dll #23 ?? from /mingw64/bin/libgtk-win32-2.0-0.dll #24 ?? from /mingw64/bin/libgdk-win32-2.0-0.dll #25 ?? from /mingw64/bin/libglib-2.0-0.dll #26 ?? from /mingw64/bin/libglib-2.0-0.dll #27 ?? from /mingw64/bin/libglib-2.0-0.dll #28 app_run #29 main at main.c line 493 Once I am done with all my exams I could try and do it again with the newest versions and maybe include the other dependencies, mentioned in the stack trace if this could help some more.
Damn, no edit function, copied the wrong version of the trace. I hope I get it right, this time:
+ Trace 236120
*** Bug 772429 has been marked as a duplicate of this bug. ***
From bug 772429: After browsing the suggested similar issues, I offer additional info that might be relevant. I run three monitors - left:1920x1200, centre (main): 1920x1200, right: 1680x1050. When the error occurred the Color Exchange dialog was displayed in the centre monitor and I was clicking the eyedropper on the left-hand monitor.
*** Bug 773324 has been marked as a duplicate of this bug. ***
*** Bug 759321 has been marked as a duplicate of this bug. ***
Hi I have also 3 Monitor and tha same Problem.
Same problem: GIMP crashes when trying to use color picker. GIMP version: 2.8.18 HP G61 Notebook PC with second monitor (SyncMaster 740BF) Intel Celeron @ 2.2Ghz 3 GB RAM Windows 10 Home version 1511 GIMP runs on the second monitor with various tools on the Notebook monitor. Procedure to reproduce problem: Open any JPG file Click on Airbrush Tool Click on Foreground color selector Click on Eyedropper tool Click anywhere in the GIMP window on second monitor Error message: "GNU Image . . . . . has stooped working . . . (etc)" Click close program (as instructed) Maybe associated problem: color picker always returns black Open any JPG file Click on Airbrush Tool Click on Foreground color selector Click on Eyedropper tool Click anywhere in a toolbox on the main (Notebook) monitor Current Foreground always returns black What additional information can I send you?
Same problem: GIMP crashes when trying to use color picker in 2 o 3 monitor. My configuration: Windows 10 Enterprise N 64 bit Ram: 8 GB Monitoring ------------------------------------------------------------------------- Mainboard Model ASUSTeK Computer Inc. Z97-P (0x00000147 - 0x0002D580) LPCIO ------------------------------------------------------------------------- LPCIO Vendor ITE LPCIO Model IT8606 LPCIO Vendor ID 0x90 LPCIO Chip ID 0x8606 LPCIO Revision ID 0x3 Config Mode I/O address 0x2E Config Mode LDN 0x4 Processors ------------------------------------------------------------------------- Number of processors 1 Number of threads 4 Processors Information ------------------------------------------------------------------------- Processor 1 ID = 0 Number of cores 4 (max 4) Number of threads 4 (max 4) Name Intel Core i5 4460 Codename Haswell Specification Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz Package (platform ID) Socket 1150 LGA (0x1) Technology 22 nm TDP Limit 84.0 Watts Core Speed 3397.9 MHz Multiplier x Bus Speed 34.0 x 99.9 MHz Stock frequency 3200 MHz Instructions sets MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, EM64T, VT-x, AES, AVX, AVX2, FMA3 Display Adapters ------------------------------------------------------------------------- Display adapter 0 Display name \\.\DISPLAY1 Name Intel(R) HD Graphics 4600 Board Manufacturer ASUSTeK Computer Inc. Technology 22 nm PCI device bus 0 (0x0), device 2 (0x2), function 0 (0x0) Vendor ID 0x8086 (0x1043) Model ID 0x0412 (0x8534) Performance Level 0 Core clock 599.6 MHz Monitor 0 Model ASUS VH222H () ID ACI22F3 Serial 97LMTF051619 Manufacturing Date Week 28, Year 2009 Size 21.1 inches Max Resolution 1920 x 1080 @ 60 Hz Horizontal Freq. Range 30-85 kHz Vertical Freq. Range 55-75 Hz Max Pixel Clock 160 MHz Gamma Factor 2.2 Monitor 1 Model ASUS VH222H () ID ACI22F3 Serial 97LMTF051623 Manufacturing Date Week 28, Year 2009 Size 21.1 inches Max Resolution 1920 x 1080 @ 60 Hz Horizontal Freq. Range 30-85 kHz Vertical Freq. Range 55-75 Hz Max Pixel Clock 160 MHz Gamma Factor 2.2 Monitor 2 Model ASUS VW193D () ID ACI19D5 Serial 9CLMTF031377 Manufacturing Date Week 49, Year 2009 Size 19.1 inches Max Resolution 1440 x 900 @ 59 Hz Horizontal Freq. Range 30-83 kHz Vertical Freq. Range 55-75 Hz Max Pixel Clock 150 MHz Gamma Factor 2.2 Error: Bucket errato 120514208057, tipo 4 Nome evento: APPCRASH Risposta: Non disponibile ID CAB: 0 Firma problema: P1: gimp-2.8.exe P2: 2.8.18.0 P3: 00000000 P4: libpixman-1-0.dll P5: 0.0.0.0 P6: 7065725f P7: c0000005 P8: 000000000008a990 P9: P10:
I hope the problem will be fixed quickly. It is very annoying Thanks so much
We have zero windows developers. It will only be fixed if you or somebody fixes it, or sends us somebody who can.
Why even bother releasing this software on windows if you know it is broken, and won't fix it?
That's a pretty good question... which I better don't answer.
It works well enough for many people, who happen to be quite happy for being able to use it.
Agreed. GIMP is an awesome app on Windows even with this annoying little inconvenience. I would not expect the dropper bug to be fixed soon even if a Windows developer does become available (unless lucked upon while working bigger issues) - it only affects Windows users with 3 or more monitors and is pretty easy to work around.
Agree also. For its complexity, power and utility, Gimp is pretty stable. @Paul you mentioned a work-around - is this documented anywhere?
@RrnR - The bug only cause Gimp to crash is you use the eyedropper from the color dialog. If you use the one from the regular toolbox it's fine.
Good, thanks for the alternative way :-)
@RrnR, In my case, the color picker works fine on my first two monitors in Windows so I just avoid sampling on additional monitors. Or you can use the one in the toolbox as Tony suggests or download a sampler - there are plenty of free RGB sample tools out there. And of course you can always run GIMP under Linux if that is an option.
Recently installed GIMP 2.8.20 Same problem: GIMP crashes when trying to use color picker. GIMP version: 2.8.20 HP G61 Notebook PC with second monitor (SyncMaster 740BF) Intel Celeron @ 2.2Ghz 3 GB RAM Windows 10 Home version 1511 GIMP runs on the second monitor with various tools on the Notebook monitor. Procedure to reproduce problem: Open any JPG file Click on Foreground color selector Click on Eyedropper tool Click anywhere in the GIMP window on second monitor Error message: "GNU Image . . . . . has stooped working . . . (etc)" Click close program (as instructed) Maybe associated problem: color picker always returns black Open any JPG file Click on Foreground color selector Click on Eyedropper tool Click anywhere in the GIMP window on the main (Notebook) monitor Current Foreground always returns black What additional information can I send you?
I can replicate this 100% of the time using 2.8.14 and 2.8.20 using any of the instructions above (dropper tool in color picker dialog). Using a Dell Latitude E5450 using a DisplayLink + 3 monitors. Using Intel HD Graphics 5500 at 1080. On Windows 10 Pro 10.0.10240.
Kevin, welcome to this bug :) By any chance, do you know how to debug and perhaps fix this? Our lack of windows developers will make this stay unfixed forever unless somebody comes along and just fixes it.
I don't know C all that well, but I'll take a crack at resolving the issue.
Created attachment 348107 [details] Catchsegv log of the crash with stack trace It looks like `gdk_cairo_set_source_window (cr, root_window, -x_root, -y_root);` and `cairo_paint(cr);` in libgimpwidgets/gimppickbutton-default.c:216ish is causing the issue on users that use USB docks (like my Displaylink dock) to extend the displays. It seems to work fine if you've connected to a monitor directly to the video card without the dock. I've attached the catchsegv log to this, which has some useful information. I thought it might be an out of bounds issue, but both x_root & y_root are within the bounds of *screen, and *screen accurately returns the correct widths & heights for the multiple screens (`gdk_screen_get_width(screen)` returns 5760 on 3 screens, and 1920 on 1 screen). Is this a bug in `gdk_cairo_set_source_window`? Is there an alternative way of setting the source to the chosen pixel, instead of using `gdk_cairo_set_source_window`? I also had a question on a related note... why is `gdk_cairo_set_source_window` called with negative x_root and y_root values?
@Kevin are you implying the problem is confined to USB extension displays? I can reproduce the issue on my system (all 3 monitors on NVIDIA GeForce GTX 745, 2 digital, one analog).
FWIW, I'm using 2 monitors directly connected to my videocard.
>It seems to work fine if you've connected to a monitor directly to the video card without the dock. Nope, I am not using such a dock. All three monitors are directly connected to the video card (Nvidia GTX980 if this helps). The monitors are sorted 1 - 2 - 3 and 2 is my main monitor.
(In reply to RrnR from comment #46) > @Kevin are you implying the problem is confined to USB extension displays? > I can reproduce the issue on my system (all 3 monitors on NVIDIA GeForce GTX > 745, 2 digital, one analog). Hmm... it is for me. It doesn't seem to replicate when I have my monitors attached without the dock.
I can't reproduce it with 2.8.18 on my Macbook Pro. (Windows 10 build 1607; Intel Iris Graphics 6100; 3 monitors: 2560x1600 (internal display), 1440x2560, 1440x2560). It was reproducable on my desktop PC on an old build a couple of years ago (see report above). Notable differences: 1. My desktop had 3 external displays driven by 2 x NVidia GPUs; my laptop has 1 internal and 2 external displays driven by 1 x Intel integrated GPU 2. My desktop has NVidia GPUs; my laptop has Intel GPUs 3. My desktop ran Windows 8.1; my laptop runs Windows 10 4. The GIMP version on my desktop was probably different... (however it seems like this is still an issue) > I also had a question on a related note... why is `gdk_cairo_set_source_window` called with negative x_root and y_root values? At a guess? It's the window-local coordinates of (0,0) in the window's parent's coordinate system. (I've never used gdk, but hopefully something somewhere takes into account that Windows supports negative display coordinates...?? (0,0) is the top left of your main display. If you've got a display to its left, that display has negative coordinates.)
@Kevin, have you tried moving GIMP to the other monitors? As I explained in my case a while back, if GIMP is on the primary monitor, I don't see any issue. However, if GIMP is on one of my other 2 monitors, or even with GIMP split across 2 monitors, as soon as I color-pick a pixel that is displayed on one monitor, GIMP crash. But the same window, still split across the same 2 monitors, if I color-pick a pixel on my primary monitor, no crash. Note that the window does not have to be split across 2 monitors, it's just to say that it's really related (in the case I have seen) to where the pixel is displayed when it's selected. Regards, Eric
I have tried setting up a cross-compiling environment for Windows 64 build but failed to do so. I followed the procedure from the GIMP wiki, and also using crossroad, but the procedure is not working, getting those compilation error: For gexiv2: Making all in . make[1]: Entering directory '/home/ehoffman/gexiv2' m4 '--define=_VERSION_MAJOR_=0' '--define=_VERSION_MINOR_=10' '--define=_VERSION_MICRO_=4' gexiv2/gexiv2-version.m4 > gexiv2/gexiv2-version.h make[1]: *** No rule to make target 'gexiv2_vapi.stamp', needed by 'gexiv2.vapi'. Stop. make[1]: *** Waiting for unfinished jobs.... make[1]: Leaving directory '/home/ehoffman/gexiv2' Makefile:1274: recipe for target 'all-recursive' failed make: *** [all-recursive] Error 1 For Gimp (of course, missing gexiv2): - Error: missing dependency gegl *** Could not find gegl in your PATH. - Error: missing dependency gdk-pixbuf-csource *** Could not find gdk-pixbuf-csource in your PATH. - Error: missing dependency gexiv2 >= 0.10.3 - Error: missing dependency libpng >= 1.6.25 I don't doubt the procedures, but I think they are just out of date... This was within Ubuntu environment (actually KDE NEON). I will try again with Win32 build, without using mingw-w64, and see if I can get it to compile, and if I can get it to show the same issue under Win32. Eric
Here is my latest take on the problem (See also my comment 41 above for system specs): It seems it does not matter which monitor the GIMP main window or tools are on. BUT (and I find this most important) the primary monitor MUST be on the left of your setup. At least I found that with my setup. My second monitor is always on the left of my laptop. The crash occurs if the laptop is the primary monitor (to the right of the second monitor). I changed the second monitor (on the left) to be the primary and the problem is solved. For completeness sake I then moved the second monitor (now the primary) to the right of the laptop (not physically, but using the display settings). Problem was the same as before: crash if picking on the laptop (now on the left), and return black if picking on the second monitor (now the primary on the right). I don't know how to fix the problem, but my analysis is prompted by Kevin's comment 45 and Tom's comment 50 above: it seems that negative coordinates are the cause of both symptoms.
Can confirm, having the primary monitor on the right and the secondary monitor on the left = crash, primary monitor on the left and secondary monitor on the right = no crash.
The problem here is not how we use the API, somebody needs to dig into the windows-specific code in GDK and cairo and figure what is happening when picking from those monitors. Or write a windows specific GimpPickButton backend that uses some other way of picking the pixel. Eric, maybe you want to join #gimp on IRC, there are people who can help you with cross compiling.
I have investigated the issue, and the root cause of the crash comes from libcairo. However, the main issue is a poorly supported Win32 environment by both cairo and gtk2, when multiple monitors are involved. To have the issue, you must have at least 2 monitors, with a monitor on the left side of the primary monitor. When this environment is setup, you have an issue with cairo, which does not handle properly having a primary DC with a negative offset origin. Effectively, on Win32, you will get your primary monitor that start with the upper-left corner being at position (0,0), while the monitor on the left will start at (-1920,0) (or something similar, depending on your monitor resolution and arrangement). In the following examples, I will use my setup as a reference (3 monitors, all full-hd (1920x1080), side by side, primary in the middle). It all start in the GIMP function gimp_pick_button_pick(), file libgimpwidgets/gimppickbutton-default.c. That function: - Create a target cairo image, 1x1 pixel - Set the cairo source window to the GDK root window (the whole raw screen), so that the picel you clicked on get placed over the target image. - Perform a cauro 'paint', which will paint the sorce to the target (effectively copying the pixel from the main screen to the target image. - Move on with that extracted pixel... This works in most cases, but fail with Win32 multi-monitor setup. Here's why... When calling gdk_cairo_set_source_window(), GDK create the cairo surface from the whole screen. Cairo, in this case, when it create it's 'root' surface, will call GetClipBox() Win32 function, to get the extent of the whole screen (which return left=-1920, top=0, right=3840, bottom=1080). So, cairo set the extent of that WIN32 surface x=-1920, y=0, width=5760, height=1080. That is exceptional (in the sense that this occur only in our very specific OS/Monitor setup), but is legitimate. Plus, other programs built on top of cairo are probably used to this fact. So, so far it's correct. The issue is what come after. In fact, cairo have 2 main issues, one which is actually the root cause of the crash we are seeing in GIMP, and one that would prevent properly accessing the primary Windows surface properly (in other words, even with the crash 'fixed', GIMP would not properly get the pixel you are color-picking). So, gdk_cairo_set_source_window() returns, setting cairo source. After that, GIMP call cairo_paint(), never to come back... The crash itself originate from (for those who wish to know, and who can access the cairo GIT sources) this sequence: A few layer deep in cairo_paint(), cairo need to access the actual bits from the main display. The generic functions provided by it's graphic core library (pixman) does not know about Windows, and display contexts (DC), and all of the different devices flavors. So, cairo will first need to provide an abstraction layer to pixman, so that pixman can just do it's bit copying stuff from a source memory location to a target memory location. cairo will call a device/OS-specific function, and get a memory pointer for the surface. This cairo process is called creating an 'image map', and is device/OS-specific. cairo first create a map the whole screen, to cache the whole screen to memory. Function _cairo_win32_display_surface_map_to_image(), in file src/win32/cairo-win32-display-surface.c, is responsible to map a win32 surface (that is, one directly associated with a Win32 DC, like you get when calling GetDC(), CreateCompatibleDC(), etc.), in our specific case it's the main Windows DC, that we got from gdk_cairo_set_source_window(). This function will first create a 'memory DC' and do a BitBlt from the screen DC to the memory DC. Then, once in memory, the function will use the generic mapping function over that memory DC to create a cairo memory image map. All of this is done for extents x=-1920, y=0, width=5760, height=1080. This is where it hurts... First, the function start by caching the whole display to memory. The main screen DC really is starting at (-1920,0). The memory DC is however wrongly created assuming that this starting point is always 0,0 or positive. To calculate the memory DC size, it uses formula 'new memory DC width = extents.x + extents.width'. So, it find the extent lower/right corner and create a memory DC (which is always created with an origin of 0,0) which will encompass the original surface. So, if the original extent were to start at 10,10 and be of width/height of 5,5 (effectively having a lower/right corner at 15,15), the the memory DC is created with width/height 15,15. All of this is assuming (read 'forgetting, omitting, ignoring, not knowing, ...') that the original surface extent top/left corner could be negative. In this case, it is. So, the memory DC is created (in my original case) with size 3840x1080. After that, the BitBlt is made from original DC to memory DC with the same source and destination bounding rectangle (extent). With an extent of (10,10) to (20,20), that would effectively do a BitBlt for just the pixels from the original extent. In our case however, it does a BitBlt from source (-1920,0) to destination (-1920,0) of width 3840x1080. Windows will clip this and effectively BitBlt from (0,0) with size 1920x1080 (i.e. only the primary monitor). That's a bummer, but is not in itself what cause the crash. What would be correct would be to properly size the memory DC, and do the BitBlt from source DC top-left corner (-1920,0) to destination DC top-left corner (0,0). And somehow accounting for the offset. The second part of _cairo_win32_display_surface_map_to_image() is to actually create the image map (create a cairo surface image). It calls a generic image map function for this, which end up calling _cairo_image_surface_map_to_image() _cairo_image_surface_map_to_image() simply create an image using the adjusted starting memory location, using the original image 'stride'. It does computation of the new image memory pointer from original image memory with the original extent (x=-1920). So it will go 1920 pixels before the actual image (1920 times 4 bytes per pixel). And it will give that new pointer to all the functions that follow, and eventually to pixman, which will do the image copy and crash. However, the crash itself is not so because the source memory is computed 8KB before the actual image. That in itself would probably just give a bad pixel color to the color picker, since that bad memory location is just read. It's really sneaky, and I would personally never found out why without using a debugger... Can you?! If you take the actual computation code for the new image pointer, it is: data = other->data; data += extents->y * other->stride; data += extents->x * PIXMAN_FORMAT_BPP (other->pixman_format)/ 8; where: - 'data' is the new pointer. - 'other->data' is the original image pointer (0x0bb50000 in my test). - 'extents->x' and 'extents->y' are (-1920,0) here. - 'other->stride' is the original image stride (i.e. the number of actual bytes per lines, which is at minimum the image width in bytes, but can be larger). It comes from our constructed original image, which was constructed with a width of 3840 pixels (so with 4 bytes per pixel, stride is 15360). - 'other->pixman_format' is an enum, with the enum value constructed from the image format (of interest here, the high 8 bits, i.e. bits 24..31, is the number of bits per pixel). - 'PIXMAN_FORMAT_BPP (other->pixman_format)' is a macro which give the number of bits per pixel (32 bits in this case). It's just (((f) >> 24)) So, it's a basic computation, but what would that give? If we take the values above, it can be substituted as data = 0x0bb50000; data += 0 * 15360; data += -1920 * (32)/ 8; The second line does nothing, so we basically have data = 0x0bb50000; data += -1920 * (32)/ 8; One would expect to get a memory location that is 7680 bytes before, or address 0x0bb4e200. However, what you get is address 0x2bb4e200! And *that* is the address that crash pixman (and GIMP along the way). Why is that so... To add to the confusion, the formula with this: data += extents->x * PIXMAN_FORMAT_BPP (other->pixman_format)/ 8; give the wrong result, while the formula: data += extents->x * (PIXMAN_FORMAT_BPP (other->pixman_format)/ 8); give the proper result. It's a question of signed/unsigned multiplication. Everything here is signed, except other->pixman_format, which is an enum (and end-up unsigned). So, in the 2 example above, you have data += (int)-1920 * (unsigned)32 / (int)8 vs data += (int)-1920 * ((unsigned)32 / (int)8) C99 standard dictate that a multiplication of the signed int and unsigned int will always give an unsigned int. So, the 2 equations will give (using 32-bit operations, discarding overflow): data += (int)-1920 * (unsigned)32 / (int)8 data += ((unsigned)0xFFFFF880 * (unsigned)32) / (int)8 data += ((unsigned)0xFFFE1000) / (unsigned)8 data += (unsigned)0x1FFFE200 vs data += (int)-1920 * ((unsigned)32 / (int)8) data += (int)-1920 * ((unsigned)32 / (unsigned)8) data += (int)-1920 * (unsigned)4 data += (unsigned)0xFFFFF880 * (unsigned)4 data += (unsigned)0xFFFFE200 So, a nasty signed/unsigned multiplication that is bound to fail. But really is caused by the negative initial extent (which is bogus in the first place here). Phew... that long! But what can be done, the easiest would be for GIMP to fallback to use Win32 functions directly when compiling under Windows, for this function. Maybe an #ifdef WIN32 or something similar, which detect if the root window origin is non-zero, and use Win32 code directly. The right thing to do would be to fix cairo itself (not your responsibility though!), butconsidering the small user base that uses Windows, combined with the small user base that have multi-monitor setup, combined with the user base that actually are contributors to cairo, that does not make for a high user base who can correct the issue on the cairo side! I could write up a Win32 fallback patch, as I'm probably one of the very few headcount who have a Windows dev. setup :-) To follow in the coming days... Regards, Eric
Nice and complete explanation. Can you do more of these for all of the weird bugs specific to the Windows platform, please? As for fixing it, short-term will have to be a workaround in GIMP. But it seems like you could also provide a patch to cairo and/or pixman? If they publish fixed versions, we could then depend on those and make the GIMP workaround conditional on that as well.
Indeed Eric, holy shit. We keep you!
That was my intention to do a quick Windows patch, although I do this as a spare time hobby (although I'm pretty involved in it those days!). A few hours a day, which should be sufficient :-) I also happen to have done Windows GDI programming, although that was 20-some years ago, but looking through cairo code un-rusted some good old time memory. I assembled a quick demonstration to illustrate the root of the miscalculation, as a food for taught... #include <stdio.h> typedef enum { ONE = 1, TWO = 2, THREE = 3, FOUR = 4, FIVE = 5, SIX = 6, SEVEN = 7, EIGHT = 8, NINE = 9, TEN = 10 } number_enum; void main(void) { number_enum ten = TEN; int minus_ten = -10; int result; result = minus_ten * TEN / 10; printf("result 1 = %d\n", result); result = minus_ten * ten / 10; printf("result 2 = %d\n", result); } Compile and run this, you'll see the results (which by the way is a perfectly correct implementation of the C99 standard). This come from the fact that multiplying a signed and unsigned is done by converting to a common type, which in this case C99 dictate it's unsigned. The first case, TEN is a enumeration constant, which C99 dictate is took as a int (signed). The second case, 'ten' is an enum type, which is implementation-dependent, and turn out to be unsigned here (i.e. with GCC). This cascade to every operations being done as unsigned, completely messing up the (intended/expected) result. cairo could need a fix, and the GDK library also would need a fix in the sense that it does return (when I click a pixel on the first monitor) an event with a coordinate starting from (0,0). Also the gtk2 does have a few patch here and there to compensate for win32 multi-monitor, but this case seem to not have been covered. So the gimp_pick_button_pick() function will be told that a pixel was clicked at position (10,10) when, logically, according to the root window extent, GDK should have generated an event with coordinate (-1910,10). Specifically, the function gdk_window_get_origin(), which the doc say 'Obtains the position of a window in root window coordinates' does not work as documented in this case. It return (in my case) location (-100,-100) where it should have returned (-2020,-100), i.e. an off-screen location. It seem that the event widget properly return the x/y click position relative to the widget (to which the position of the widget itself is added to get the real click position), but the returned position of the widget GdkWindow itself is wrong. cairo paint function would also then need to account for the positioning of the root surface extent. i.e. if no offset is given to re-position the surfaces, a paint from a source surface to the root window should paint to the primary monitor, at offset (0,0), and not the surface top-left (which really is in this case (-1920,0)). So that makes up for a fix in both cairo and gtk2. So that both libraries get in sync with the coordinates. The issue is probably very limited in the extent though, as it's a very specific corner case (the reason why this was not fixed before), because it's Win32 only, and multi-monitor only, and with a monitor on the negative side of the display surface. The third case will also statistically occur in a very limited case for people with only 2 monitors, as most of the time (statistically), people with 2 monitors will place the primary monitor on the left, with the secondary starting at the same horizontal line at the primary. Most of the time, the primary is bigger, better, and the secondary is a smaller second hand monitor, for which the physical dimension will have the top of the display at equal height or lower than the bolder primary monitor. So the user will arrange the monitors (in Windows) so that the 'y' extent of that secondary will be placed with a positive offset or at offset y=0. All different scenarios where the issue is non-existent! So, this probably boil down to a few fixes here and there, but it is more a question of understanding the libraries, their internals, and the extent of applying a fix. Care must be taken to not break the existing implementation. This is what takes time. Plus make sure to fix and tests every corner cases. Although here this probably is some offsets to take into account, code that would activate only when you have a negative starting screen offset. So it's really a fun challenge in the end, but one which take a good amount of time, especially when you have the work, the wife, the kid and those other 'threads' to time-slice :-) Regards, Eric
Hello In fact, it was easier than I taught, as Win32 have a built-in function to get a single pixel color in RGB format. That function does convert from any format to RGB, so you you GIMP on a venerable HGA graphic card, the function does the conversion. The only downside is that it's slow (in the sense that it's not meant to grab a whole graphic, pixel by pixel), but was specifically designed for a function such as a color picker. For GDK, finally, it is OK, as the coordinates always start at (0,0) by design. The library does handle Win32 primary DC starting at any offset values, but it's API is always based on offset starting (0,0). So there's only a cairo issue, which should be bypassed now. This is pretty straightforward, but should be tested with different environments. Regards, Eric
Created attachment 349272 [details] [review] Win32 crash with color picker.
Review of attachment 349272 [details] [review]: I just noticed that the "DeleteDC" shall be replaced by "ReleaseDC"...
Created attachment 349273 [details] [review] Win32 crash with color picker (updated). Updated with proper call to ReleaseDC()
Do I read the last paragraphs of your comment 59 as "no, I won't do any patches for the libraries" or as "I'll do patches for them, but later"?
I will check the libcairo, as this really seem to be a big compatibility issue with the negative extent :-) After looking at gtk2, which always start at (0,0) being the top-left, even when Win32 return a negative extent, I think that this would be the simplest approach to fixing cairo. Plus, this will make cairo in line with gdk. So, in short, libcairo will not have negative extent anymore. Eric
Éric, some off-topic but if you are interested to continue hacking GIMP on Windows, you'd be very welcome. GIMP for Windows is a real mess and has so many issues (judging by all the weird bugs we get) and basically nobody to fix these. Don't hesitate to come and discuss on IRC sometimes too.
Fantastic, thanks :) Pushed to master: commit c585c99e8084998b3203b6ebf854499d074f3ee4 Author: Éric Hoffman <ehoffman@videotron.ca> Date: Thu Apr 6 23:50:26 2017 +0200 Bug 740634 - Color picker crashes when there are multiple monitors Use Windows API directly to get a screen pixel, works for all kinds of monitor layouts. libgimpwidgets/gimppickbutton-default.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-)
Bad commit reference?
Nope, that's the commit.
I might have been still pushing when hitting submit in bugzilla, bad timing :) Closing as FIXED.
Thank you very very very very very much!!!! :-))) When will be release 2.10 version?
Thank you. Sorry for the delay. Sure, I will first check for adjusting Cairo first, but I may try to find some time to check for some other possible Windows-specific issues. It's just a question of availability :-) The last 2 weeks have been pretty busy for me on my work. I'm actually a kind of workaholic software developer and I'm trying to figure out how to implement an algorithm for our work-related stuff)! For example, right now, we have an embedded system, and when it crash, it output a stack trace (the return addresses). What I want to do is to also print out the function names beside the stack trace addresses (to help track the bug). The thing is that there's above 150K functions, and that makes a lot of function names (which take space to store in this embedded system). Even if removing all duplicate functions names, just having 150K functions represented by a 4-byte address, 4-byte size, a reference to the function name, this takes around 2.5~3MB to store. However, the thing is that this is an embedded system on which every bit of ram count. For example, tho whole system code sit in 16MB of ram (code). Having a function table eat-up almost a quarter of that, for the sole purpose of helping the developers when there's a crash, it not an option. So I have to implement an algorithm and structure to cut each byte I can (150K function symbols having a 4-byte start address/4-byte size/4-byte function name pointer is just too much, so I have to do some trick, like removing all duplicate parts of the different names, using Huffman compression, etc.). Kind of remember me of the old days of DOS, with only a few KB of RAM available, for those of you old enough to remember those 'good old days' :-) ) The kind that do a lot of unmetered overtime because I actually love the job I do :-) I will stay in touch though.
*** Bug 781366 has been marked as a duplicate of this bug. ***
Hello I took a look at cairo, the root cause if the problem. I entered a bug on their Bugzilla, along with a patch for cairo. https://bugs.freedesktop.org/show_bug.cgi?id=100793 Regards, Eric
And pushed to gimp-2-8 as well. commit 33d45047b52c9f51cf0cb7a5c78aa6d7f4b0cd2f Author: Éric Hoffman <ehoffman@videotron.ca> Date: Sun Apr 30 21:17:46 2017 +0200 Bug 740634 - Color picker crashes when there are multiple monitors Use Windows API directly to get a screen pixel, works for all kinds of monitor layouts.