Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
November 28, 2007 [Issue 1695] New: Calling some functions out of PSAPI.dll corrupts stack | ||||
---|---|---|---|---|
| ||||
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]; writefln("Process #%d - PID: %d", i, pid); 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: Process #1 - PID: 4 Process #2 - PID: 780 Process #3 - PID: 836 If you use GetModuleFileNameExA() the list will be incorrect: Process #1 - PID: 4 Process #2 - PID: 780 Process #3 - PID: 836 Process #4 - PID: 4298544 Process #6 - PID: 1244976 Process #7 - PID: 4202711 Process #8 - PID: 1040 Process #9 - PID: 1288 Process #10 - PID: 1332 Process #4 to Process #8: These are invalid process id's - processes with these 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 -- |
December 30, 2007 [Issue 1695] Calling some functions out of PSAPI.dll corrupts stack | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1695 bugzilla@digitalmars.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |INVALID ------- Comment #1 from bugzilla@digitalmars.com 2007-12-30 00:55 ------- 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. -- |
October 21, 2012 [Issue 1695] implib produces wrong *.lib files | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | 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 --- Comment #2 from Denis Shelomovskij <verylonglogin.reg@gmail.com> 2012-10-21 14:58:05 MSD --- (In reply to comment #1) > 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: ------- |
October 21, 2012 [Issue 1695] implib produces wrong *.lib files | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1695 --- Comment #3 from Denis Shelomovskij <verylonglogin.reg@gmail.com> 2012-10-21 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: ------- |
April 07, 2013 [Issue 1695] implib produces wrong *.lib files | ||||
---|---|---|---|---|
| ||||
Posted in reply to d-bugmail | http://d.puremagic.com/issues/show_bug.cgi?id=1695 Walter Bright <bugzilla@digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|REOPENED |RESOLVED Resolution| |WONTFIX --- Comment #4 from Walter Bright <bugzilla@digitalmars.com> 2013-04-07 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: ------- |
Copyright © 1999-2021 by the D Language Foundation