WTF is going on! Corrupt value that is never assigned
FoxyBrown via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Jul 13 11:22:34 PDT 2017
The following code is pretty screwed up, even though it doesn't
look like it. I have a buf, a simple malloc which hold the
results of a win32 call. I am then trying to copy over the data
in buf to a D struct.
But when copying the strings, the buf location changes, screwing
up the copying process. It shouldn't happen, buf never changes
value anywhere except the first malloc(which is once). Somehow it
is getting changed, but where?
The specific win32 or style is irrelevant, I am talking either
about a bug or some subtle D thing because the code makes sense.
(Fill Buf, iterate through buffer copying over to D values).
I've ran in to this before, D does something fishy and it wastes
hours upon hours trying to track done some stupid little thing it
does.
The buf value changes when calling cstr2dstr but I've had it with
other values to(any function call such as to!string, etc seems to
trigger it).
struct ServiceData
{
wstring Name;
wstring LongName;
int Type;
int State;
int ControlsAccepted;
int Win32ExitCode;
int SpecificExitCode;
int CheckPoint;
int WaitHint;
int ProcessId;
int Flags;
}
auto cstr2dstr(wchar* cstr)
{
import std.array;
auto str = appender!wstring;
auto len = lstrlen(cstr);
str.reserve(len);
for(int i = 0; i < len; i++)
str.put(cstr[i]);
return str.data;
}
auto EnumServices()
{
import core.stdc.stdlib, std.traits;
ServiceData[] servicesList;
auto buf = malloc(50000); // Gets changed later, even though
never an assignment
auto buf2 = buf; // does not change
auto schSCManager = OpenSCManager(null, null,
SC_MANAGER_ALL_ACCESS);
if (NULL == schSCManager)
{
print("OpenSCManager failed (%d)\n", GetLastError());
return servicesList;
}
DWORD dwBytesNeeded, dwCount, lpResumeHandle, resume, totalCount;
auto servicesType = (SERVICE_DRIVER | SERVICE_FILE_SYSTEM_DRIVER
| SERVICE_KERNEL_DRIVER | SERVICE_WIN32 |
SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS);
int cnt = 0;
auto res = 0;
do
{
// Manually copy over data, this is because EnumSErvicesStatus
adds data at end of array for some odd ball reason making it
difficult to build the correct array sequentially
for(int i = 0; i < dwCount; i++)
{
ENUM_SERVICE_STATUS_PROCESSW x;
ServiceData d;
auto s = cast(ENUM_SERVICE_STATUS_PROCESSW*)(buf +
i*ENUM_SERVICE_STATUS_PROCESSW.sizeof);
// before buf is of correct value
d.Name = cstr2dstr(s.lpServiceName);
// after buf is invalid, yet buf is never
assigned
}
res = EnumServicesStatusExW(schSCManager,
SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO, servicesType,
SERVICE_STATE_ALL, cast(ubyte*)buf, 50000, &dwBytesNeeded,
&dwCount, &resume, cast(const(char)*)null);
if (ERROR_MORE_DATA != GetLastError()) { print("Error
enumerating services."); break; }
} while (res == 0);
for(int i = 0; i < totalCount; i++)
{
auto s = servicesList[i];
writeln(s.Name, " - ", s.LongName, " - ", s.Type, " = ",
s.State);
}
return servicesList;
}
More information about the Digitalmars-d-learn
mailing list