Comment #0 by verylonglogin.reg — 2012-11-02T07:11:54Z
This is catastrophic Windows druntime issue.
Triggering code:
---
void main()
{
throw new Exception("Ex"); // or Error, or any Throwable
// try throw new Exception("Ex"); catch { } // same here
}
---
Want something really long? Lunch this on Windows:
---
import std.file;
void main()
{
chdir(`C:\`);
try
// Let's serach the whole C: drive!
throw new Exception("Ex");
catch { }
}
---
Since dmd 2.060.
Comment #1 by alex — 2012-11-02T07:13:50Z
I don't have a Windows machine available. Do you know where in druntime this search is being triggered?
This is...kind of bad.
Comment #2 by andrej.mitrovich — 2012-11-02T07:18:59Z
My best bet is that new dbghelp.dll code which tries to find dbghelp.dll is causing the search.
Comment #3 by verylonglogin.reg — 2012-11-02T07:33:05Z
(In reply to comment #6)
> It's damn hard to find matching DMD+druntime+phobos versions that compile
> together for that pull so I can't test these out.
Just use the latest versions of everything, but the older version of the stack trace code.
Comment #8 by dmd — 2012-11-22T02:54:27Z
The root cause is that druntime/core/sys/windows/stacktrace.d::static this() calls WinAPI's SymInitialize() with a NULL user path. This results in the default path:
%CWD%;%_NT_SYMBOL_PATH%;%_NT_ALTERNATE_SYMBOL_PATH%
as per the MSDN documentation here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms681351%28v=vs.85%29.aspx. Unfortunately, I cannot repro this behavior on Windows 7 Home Premium SP1, dbghelp.dll 6.1. I suspect that newer versions of dbghelp.dll are simply more clever than what MSDN states (for instance, if the semantics were changed to make the default path start with the image location, 99% of all directory scanning would be eliminated; also, it is pretty silly to not have this as the default behavior).
Please report which version of dbghelp.dll you are using. There are likely multiple versions present on your machine, so you can discover the one being used via 'where':
where dbghelp.dll
It will most likely discover the version in %SystemRoot%\system32. You can find the version in the file properties.
Assuming that this is truly only a problem with older versions of dbghelp.dll (e.g.: 5.x versions), it is not difficult to simply provide a custom user path starting with the current executable image path. However, I do not have a means to verify the fix, as I cannot repro the actual problem.
Comment #9 by code — 2012-12-07T09:37:27Z
I don't quite understand the issue here. Why is it a problem that is searches for appropriate .pdb files?
Comment #10 by verylonglogin.reg — 2012-12-07T10:54:25Z
(In reply to comment #9)
> I don't quite understand the issue here. Why is it a problem that is searches
> for appropriate .pdb files?
Because the search may require hours for every thrown (cached or not) exception (even in release build).
Comment #11 by code — 2012-12-07T11:42:05Z
(In reply to comment #10)
> (In reply to comment #9)
> > I don't quite understand the issue here. Why is it a problem that is searches
> > for appropriate .pdb files?
>
> Because the search may require hours for every thrown (cached or not) exception
> (even in release build).
Are you sure? It should only search for the appropriate pdbs on the first throw.
Comment #12 by andrej.mitrovich — 2012-12-07T12:55:19Z
(In reply to comment #11)
> (In reply to comment #10)
> > (In reply to comment #9)
> > > I don't quite understand the issue here. Why is it a problem that is searches
> > > for appropriate .pdb files?
> >
> > Because the search may require hours for every thrown (cached or not) exception
> > (even in release build).
>
> Are you sure? It should only search for the appropriate pdbs on the first
> throw.
Yes we're sure. I can personally hear it scraping my hard drive for a dozen seconds before I get a stack trace.
Comment #13 by code — 2012-12-07T13:51:43Z
I have a improved version of the stacktrace class at:
https://github.com/Ingrater/druntime/blob/master/src/core/sys/windows/stacktrace.d
It's more similar to the unix interface as you can first query a list of addresses and then resolve it later. This might fix the issue as the resolving of the symbols could be delayed until it actually needs to be printed instead resolving at throw time. I'm also no longer calling SymInitialize with NULL, so this should fix the other issue too.
I wanted to do a pull request for this soon, but I currently don't have time for it. So if it is super critical someone else might want to do it.
All the version(NOGCSAFE){...} parts can just be removed from the file.
I can not reproduce this. I even tried it on a windows XP machine with a very old version of dbghelp. What system did you run this on? Please post the version numbers of your dbghelp.dll and imagehlp.dll (in your Windows/System folder or Windows/sysWOW64 if you are using a x64 windows)
Kind Regards
Benjamin Thaut
Comment #16 by andrej.mitrovich — 2012-12-23T06:48:59Z
Created attachment 1171
procmon
Comment #17 by andrej.mitrovich — 2012-12-23T06:49:31Z
(In reply to comment #15)
> I can not reproduce this. I even tried it on a windows XP machine with a very
> old version of dbghelp. What system did you run this on? Please post the
> version numbers of your dbghelp.dll and imagehlp.dll (in your Windows/System
> folder or Windows/sysWOW64 if you are using a x64 windows)
>
> Kind Regards
> Benjamin Thaut
---
import std.file;
void main()
{
chdir(`C:\`);
try
// Let's serach the whole C: drive!
throw new Exception("Ex");
catch { }
}
---
I've added just a partial log of sysinternals process monitor with a filter on 'test.exe' from the above example.
Comment #18 by andrej.mitrovich — 2012-12-23T14:48:55Z
(In reply to comment #17)
> Hi,
> did you use druntime version 2.060 to reproduce the issue or did you use the
> latest druntime from the git master branch?
> If you used the 2.060 version I think I know where the issue is.
git-head with git-druntime.
However I can recreate it with 2.060 dmd+druntime.
Comment #19 by code — 2012-12-23T15:19:25Z
I have a possible fix at:
https://github.com/Ingrater/druntime/tree/pull8936
As I can't reproduce the issue, I can't tell if this actually fixes the issue.
It would be great if someone who can reproduce this, could check the fix and report the results.
Kind Regards
Benjamin Thaut
Comment #20 by andrej.mitrovich — 2012-12-23T15:22:56Z
(In reply to comment #19)
> I have a possible fix at:
> https://github.com/Ingrater/druntime/tree/pull8936
>
> As I can't reproduce the issue, I can't tell if this actually fixes the issue.
> It would be great if someone who can reproduce this, could check the fix and
> report the results.
>
> Kind Regards
> Benjamin Thaut
I've just tried it, same results as before.
Comment #21 by code — 2012-12-23T15:27:12Z
Could you compile the debug(PRINTF) version and post which search path is printed to the console?
And with same results you mean it is still searching your whole C drive?
Kind Regards
Benjamin Thaut
Comment #22 by andrej.mitrovich — 2012-12-23T15:30:29Z
(In reply to comment #21)
> Could you compile the debug(PRINTF) version and post which search path is
> printed to the console?
Search paths: C:;C:\WINDOWS;
> And with same results you mean it is still searching your whole C drive?
Yes.
Comment #23 by code — 2012-12-23T15:34:50Z
Where is your binary located? If you put it directly into the C:\ root then it obviously will have to search the whole C drive for pdbs.
Kind Regards
Benjamin Thaut
Comment #24 by andrej.mitrovich — 2012-12-23T15:37:20Z
(In reply to comment #23)
> Where is your binary located? If you put it directly into the C:\ root then it
> obviously will have to search the whole C drive for pdbs.
>
> Kind Regards
> Benjamin Thaut
Why does it obviously have to search the entire drive? It doesn't do that in 2.059 and I get a nice stack trace. The whole point of that test-case is that the path the executable is located in is needlessly search for.
Comment #25 by code — 2012-12-23T15:40:36Z
(In reply to comment #24)
> Why does it obviously have to search the entire drive? It doesn't do that in
> 2.059 and I get a nice stack trace. The whole point of that test-case is that
> the path the executable is located in is needlessly search for.
Because the documentation says so:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms681351%28v=vs.85%29.aspx
I also finally understood the issue. Thanks for your help. I have a fix now and will open a pull request soon.
Comment #27 by andrej.mitrovich — 2012-12-23T15:50:27Z
(In reply to comment #26)
> (In reply to comment #24)
>
> I just commited a fix to https://github.com/Ingrater/druntime/tree/pull8936
> can you please confirm it actuall works?
Yes it works now, and the search path is now:
Search paths: C:\WINDOWS;
Thanks for your work!
Before your latest commit I was going to recommend to try making the code search the Windows folder before it searches the local path. So e.g. in that commit before where I've had:
Search paths: C:;C:\WINDOWS;
maybe the simple fix would be to put the local path last:
Search paths: C:\WINDOWS;C:;
Comment #28 by code — 2012-12-23T15:54:51Z
(In reply to comment #27)
> (In reply to comment #26)
> > (In reply to comment #24)
> >
> > I just commited a fix to https://github.com/Ingrater/druntime/tree/pull8936
> > can you please confirm it actuall works?
>
> Yes it works now, and the search path is now:
>
> Search paths: C:\WINDOWS;
>
> Thanks for your work!
>
> Before your latest commit I was going to recommend to try making the code
> search the Windows folder before it searches the local path. So e.g. in that
> commit before where I've had:
>
> Search paths: C:;C:\WINDOWS;
>
> maybe the simple fix would be to put the local path last:
>
> Search paths: C:\WINDOWS;C:;
If I understood the documentation correctly the search paths are only for pdbs that are not directly referenced from the executables. For example when you use the microsoft symbol store. Specifying the path of the executable should not be neccessary at all to get correct stack traces.
Comment #29 by andrej.mitrovich — 2012-12-23T15:57:38Z
(In reply to comment #28)
> If I understood the documentation correctly the search paths are only for pdbs
> that are not directly referenced from the executables. For example when you use
> the microsoft symbol store. Specifying the path of the executable should not be
> neccessary at all to get correct stack traces.
I see. Thanks again for your time!
Could you make this a pull request so we can merge it before 2.061 release?