Suspect copy file dialog box painting far too frequently

Hi All,

I have a fileserver which I control with Remote Desktop in Windows XP and I run DOpus on there.

I have noticed that when copying large files on my fileserver with DOpus the CPU on the remote AND local machine goes thru the roof.

For example copying a 2.7GB file from physical drive to drive takes around 30% of remote CPU in Windows Explorer and no noticable increase in local CPU.

However when I use DOpus it goes to 80+% with no improvement in thruput speed (thinking that's why the extra CPU). Then I noticed that my local machine's CPU was being used up at the same time I did a copy and it was mstsc.exe (The RD application) and it fluctuated between 50% and 90%.

Now to me that sounds like the remote dialog box data is being updated very frequently which is then being replicated locally. I have the "Show progress bar speed timer when copying ..." flag enabled but it looks like it's being updated far too frequently and is flooding the RD application.

So as a test I disabled the show progress option to get the minimum copy dialog (filename and progress bar with percentage) and tried the copy again. No difference in CPU usage.

That leads me to suspect that it's the progress bar being updated/repainted that's the issue.

Can anyone else replicate this?

It's a common thing I have hit when writing progress GUI's where the callback function just paints irrespective of how many time's it's called. Usually I have "fixed" the issue by only updating the progress when there's a whole percentage change so you are guarenteed it's only going to happen 100ish times. Maybe it's something that should be done here?

UPDATE: Looks like I could be right as if I hide the dialog or put another window over it the CPU on my local machine drops down to normal levels.

I think you may have something here - currently the progress bar updates every time a chunk of data is read or written, which at the default buffer size of 64k is going to be a lot of updates for a 2.7GB file.

We'll change this in the next version to update the progress bar a bit more sensibly.

Opus includes a change which should address this issue.

I'd be interested to know if the changes have helped.

I'll test it tonight for you guys.

I can confirm that this issue is now resolved. CPU usage on the server fluctuates at around 20% and the client never moves.

Thanks for fixing it.

I have an OT question though. When I installed DO (unicode version) it had to reboot the machine, even though I had terminated DO and all instances of Explorer (including the taskbar). I remember it did this when I installed the last version. Is this deliberate?

No, it only does it if needed. Something else must have had the library (dopuslib.dll) open for some reason.

(ps: glad the progress bar is all good now :slight_smile:

I've noticed mIRC holding dopuslib.dll open sometimes. Not sure why some programs do and other don't; might be the order they're launched, or happen to programs launched from Opus or something? Hard to say.

I've always assumed that dopuslib.dll gets loaded into other processes because of the keyboard hook that enables system-wide macros, but I might be wrong.

Ahhh ... global keyboard hooks.

I have been pulling my hair out as to what that library was. I use boundscheker on my code and it kept reporting that library was leaking memory.

Any way to disable the hooks?

There aren't any global keyboard hooks - the hotkeys are done through a standard API function (can't remember which - RegisterHotkey() ?)

Opus sets up a mouse hook on the desktop window but other than that it doesn't go into any other process. If something else loads dopuslib.dll into it's process I have no idea why!

Hi Jon,

Is there any way to disable the hotkeys and mouse hooks anyway? It's annoying when trying to track down leaks when 90% are nothing to do with my app.

I used to notice dopuslib.dll being loaded by my own programs in the debugger (along with a hoard of other DLLs I wasn't explicitly using), although I just tried it and it doesn't happen today on this machine.

It's been a while since I did much C++ debugging, except of Opus plugins (where I'm debuggnig inside dopus.exe in the first place :slight_smile:), so it may have stopped happening several versions of Opus or Windows ago.

You think they're due to Opus, or something else? Sounds like Opus doesn't actually hook other apps, except for Explorer's desktop window.

Boundscheker is reporting the resource leaks from the DLL. If I get a chance tonight I'll post the log.

If that's the case then, yeah, it would be useful to eliminate the DLL from your process. (I take it you are seeing it added to your processes like I used to see myself?)

The BoundsChecker reports may be false alarms* but I agree that it's still helpful to eliminate as many DLLs as possible so you get fewer false alarms.

(* While they may be real leaks, BoundsChecker (unless they've added something magic since I last used it) often prints false positives about leaks in DLLs because its own DLL isn't always loaded first or unloaded last so it's memory snapshop can't take everything that other DLLs allocate/free into account. Without changing Windows itself there is probably nothing BC can do to improve this, but I do remember it being annoying that I had to spend time investigating leak reports which turned out to be false alarms due to DLL load order, so I feel your pain!)

I used vs2005's new project wizard to create a default Windows application, no MFC/ATL/etc and from the screenshot you can see what I got when the app exited (from file/exit in the menu).

Also here's what I got in VS when I ran it:

'Test3.exe': Loaded 'D:\Development\Perforce\C\Test3\debug\Test3.exe', Symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\user32.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c\msvcr80d.dll', Symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\shimeng.dll', No symbols loaded.
'Test3.exe': Unloaded 'C:\WINDOWS\system32\shimeng.dll'
'Test3.exe': Loaded 'C:\WINDOWS\system32\uxtheme.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\MSCTF.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\CTAGENT.DLL', Binary was not built with debug information.
'Test3.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9\comctl32.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\shlwapi.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\mslbui.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\Program Files\GPSoftware\Directory Opus\dopuslib.dll', Binary was not built with debug information.
'Test3.exe': Loaded 'C:\WINDOWS\system32\version.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\comdlg32.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\shell32.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\ole32.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\oleaut32.dll', No symbols loaded.
'Test3.exe': Loaded 'C:\WINDOWS\system32\comctl32.dll', No symbols loaded.
The program '[13676] Test3.exe: Native' has exited with code 0 (0x0).

So I can't see how BC can miss something since it loads the program directly in it's own debugging session therefore it traps all LoadLibrary's, etc.

They might be real leaks, and I haven't used BC in years so it might work differently now, but when I used it last it hooked into Visual Studio's debugger and it only started hooking allocations at a certain point early in the program (but potentially after some DLLs and/or static data was initialised) and stopped late in the program (but potentially before some DLLs had been freed and static destructors run). Or something like that...

But, either way, it looks like there's something that needs investigating in terms of are those false alarms or real leaks, and why is dopuslib.dll sometimes being loaded into unrelated processes in the first place?

I'm at home now and tried running a C++ console app as well as an MFC app under the VS2003 debugger and I don't see dopuslib.dll loaded. But I have seen it in the past. I can't think of a relevant setting or anything to try which might trigger it... It's weird.

If you have the file collections icon on the desktop and your program enumerates the desktop folder then the dll could end up being loaded. Similarly if you are doing anything with context menus and the Opus zip context menu is enabled. There are probably some other cases that could cause it to be loaded but I can't think of any off-hand.

I can reproduce the problem at will.

With DOpus running, sitting in the system tray with no listers opened the DLL is referenced.

With DOpus unloaded the DLL is not referenced.

Remember this is a simple vs2005 wizard generated app which I have included here so you can examine it to see if it does something "funny".

Well, at least I have a workaround ... just don't have DOpus running while I debug :frowning: (34.1 KB)

Problem solved then :slight_smile:

Or just tell BC to ignore dopuslib.

It's caused by enabling Desktop double-click.

When I was trying yesterday I had a test version of Opus on both machines which meant the Desktop double-click was broken (because I hadn't restarted Explorer.exe so it was still using the old version of Opus).

Having rebooted today, I see dopuslib.dll is loaded again when I debug a program. It happens the first time I move the mouse over the program's window.

But if I turn off Desktop double-click in Preferences then dopuslib.dll is no longer loaded into programs I'm debugging. So there's your way to turn it off.