digitalmars.D.bugs - [Issue 1695] New: Calling some functions out of PSAPI.dll corrupts stack
- d-bugmail puremagic.com (86/86) Nov 27 2007 http://d.puremagic.com/issues/show_bug.cgi?id=1695
- d-bugmail puremagic.com (11/11) Dec 29 2007 http://d.puremagic.com/issues/show_bug.cgi?id=1695
- d-bugmail puremagic.com (60/63) Oct 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=1695
- d-bugmail puremagic.com (13/13) Oct 21 2012 http://d.puremagic.com/issues/show_bug.cgi?id=1695
- d-bugmail puremagic.com (21/21) Apr 07 2013 http://d.puremagic.com/issues/show_bug.cgi?id=1695
http://d.puremagic.com/issues/show_bug.cgi?id=1695 Summary: Calling some functions out of PSAPI.dll corrupts stack Product: D Version: 2.007 Platform: PC OS/Version: Windows Status: NEW Severity: critical Priority: P2 Component: DMD AssignedTo: bugzilla digitalmars.com ReportedBy: mail tobias-wassermann.de 1. Generate a lib with implib: implib /noi /system psapi.lib C:\windows\system32\psapi.lib 2. Compile the following code with dmd ProcessFinder.d -L+psapi/noi import std.stdio; import std.c.windows.windows; extern (Windows) HANDLE OpenProcess(uint dwDesiredAccess, BOOL bInheritHandle, uint dwProcessId); extern (C) { BOOL EnumProcesses(DWORD* pProcessIds, DWORD cb, DWORD* pBytesReturned); DWORD GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, char* fileName, uint size); DWORD GetProcessImageFileNameA(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize); } void main(char[][] args) { uint[256] processIds; uint byteCount; char[] processFileName; int ret = EnumProcesses(processIds.ptr, processIds.length*uint.sizeof, &byteCount); if(ret!=0) { for(uint i=0; i<processIds.length && i<byteCount/uint.sizeof; i++) { if(processIds[i]==0) continue; uint pid = processIds[i]; HANDLE hProcess = OpenProcess(0x410 /* QueryInformation | VMRead */, false, pid); if(cast(int)hProcess>0) { processFileName.length = 300; uint namelength = 0; //namelength = GetProcessImageFileNameA(hProcess, processFileName.ptr, processFileName.length); namelength = GetModuleFileNameExA(hProcess, cast(HMODULE)0, processFileName.ptr, processFileName.length); processFileName.length = namelength; writefln("=> %s", processFileName); CloseHandle(hProcess); } } } } So what will happen? With commented out GetModuleFileNameExA()-call you will get a list of correct process id's: If you use GetModuleFileNameExA() the list will be incorrect: id doesn't exist, the next real id is 1288. 3. After calling GetModuleFileNameExA() the stack will be corrupted, the processIds-Array will be incorrect, if you comment out this call, all works fine. The same behaviour if you call GetProcessImageFileNameA() Strange thing: If you port the code to C and compile against DMC - same problem! If you compile it with Microsoft Visual C++, you can also use GetModuleFileNameExA() and GetProcessImageFileNameA() without any problems. Seems to be an implib-issue? See also the "Windows API: Strange behaviour after calling GetModuleFileNameExA" entries within the digitalmars.D-newsgroup --
Nov 27 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1695 bugzilla digitalmars.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |INVALID The problem is declaring Windows API functions as being extern(C). They should be extern(Windows). Stack corruption is the result of incorrectly declaring what function calling convention to use. --
Dec 29 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1695 Denis Shelomovskij <verylonglogin.reg gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED CC| |verylonglogin.reg gmail.com Version|2.007 |unspecified Resolution|INVALID | Summary|Calling some functions out |implib produces wrong *.lib |of PSAPI.dll corrupts stack |files 14:58:05 MSD ---The problem is declaring Windows API functions as being extern(C). They should be extern(Windows). Stack corruption is the result of incorrectly declaring what function calling convention to use.Looks like Walter like spending people time. As "extern(Windows)" and "extern(C)" functions has different symbol names the fact that the program links, runs and corrupts the stack just shows that `implib` generates incorrect *.lib files. Incorrect behavior example (DLL): implib /noi /system psapi-from-dll.lib %windir%\system32\psapi.dll --- pragma(lib, "psapi-from-dll.lib"); extern(C) nothrow extern void EnumProcesses(); // links fine void main() { auto p = &EnumProcesses; } --- More than that 'implib' works incorrect with '.def' files too. Incorrect behavior example (DEF): psapi.def (from mingw except library name is "PSAPI" instead of "PSAPI.DLL" because 'implib' stops on dot with error): --- LIBRARY PSAPI EXPORTS EnumProcesses 12 --- implib /noi /system psapi-from-def.lib psapi.def --- pragma(lib, "psapi-from-def.lib"); // Error 42: Symbol Undefined _EnumProcesses // or _EnumProcesses 12 for extern(Windows) extern(C) nothrow extern void EnumProcesses(int, int, int); void main() { auto p = &EnumProcesses; } --- The second issue is because 'implib' ignores '/system' switch for *.def files: implib /noi psapi-from-def-no-system.lib psapi.def produces exactly same *.lib file. The second issue has trivial workaround: one should prefix all symbols in *.def file with '_' by hands. E.g. such *.def file finally forces 'implib' to produce a correct *.lib: --- LIBRARY PSAPI EXPORTS _EnumProcesses 12 --- -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 21 2012
http://d.puremagic.com/issues/show_bug.cgi?id=1695 15:03:45 MSD --- Damn, sorry. This is the correct DEF file for 'implib': --- LIBRARY PSAPI EXPORTS _EnumProcesses 12=EnumProcesses --- (or the program will link but fail to run trying to search for '_EnumProcesses 12' symbol in psapi.dll) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 21 2012
http://d.puremagic.com/issues/show_bug.cgi?id=1695 Walter Bright <bugzilla digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|REOPENED |RESOLVED Resolution| |WONTFIX 01:23:20 PDT --- All /system does is prepend a _. See: http://www.digitalmars.com/ctg/implib.html The trouble is that the names in Windows systems DLLs use the extern (Windows) calling convention, but they don't use the extern (Windows) mangled names. The Windows mangled names have the nn suffix. The names happen to match up with the C names, but the stack treatment is different, hence the crash. There is nothing implib can do about this situation. The only thing you, as a user, can do is create a correct module definition file in order to map the internal and external names. Implib can't do that, as it doesn't have the information to do it. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Apr 07 2013