mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
[DBGHELP] Fix default search path handling. CORE-17073
* Allow NULL search path in SymSetSearchPath * Use . instead of concrete current directory * Use _NT_ALT_SYMBOL_PATH variable * Add some tests
This commit is contained in:
parent
ab7b004d51
commit
4601d94801
2 changed files with 128 additions and 37 deletions
|
@ -191,6 +191,43 @@ struct cpu* cpu_find(DWORD machine)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WCHAR* make_default_search_path(void)
|
||||||
|
{
|
||||||
|
WCHAR* search_path;
|
||||||
|
WCHAR* p;
|
||||||
|
unsigned sym_path_len;
|
||||||
|
unsigned alt_sym_path_len;
|
||||||
|
|
||||||
|
sym_path_len = GetEnvironmentVariableW(L"_NT_SYMBOL_PATH", NULL, 0);
|
||||||
|
alt_sym_path_len = GetEnvironmentVariableW(L"_NT_ALT_SYMBOL_PATH", NULL, 0);
|
||||||
|
|
||||||
|
/* The default symbol path is ".[;%_NT_SYMBOL_PATH%][;%_NT_ALT_SYMBOL_PATH%]".
|
||||||
|
* If the variables exist, the lengths include a null-terminator. We use that
|
||||||
|
* space for the semicolons, and only add the initial dot and the final null. */
|
||||||
|
search_path = HeapAlloc(GetProcessHeap(), 0,
|
||||||
|
(1 + sym_path_len + alt_sym_path_len + 1) * sizeof(WCHAR));
|
||||||
|
if (!search_path) return NULL;
|
||||||
|
|
||||||
|
p = search_path;
|
||||||
|
*p++ = L'.';
|
||||||
|
if (sym_path_len)
|
||||||
|
{
|
||||||
|
*p++ = L';';
|
||||||
|
GetEnvironmentVariableW(L"_NT_SYMBOL_PATH", p, sym_path_len);
|
||||||
|
p += sym_path_len - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alt_sym_path_len)
|
||||||
|
{
|
||||||
|
*p++ = L';';
|
||||||
|
GetEnvironmentVariableW(L"_NT_ALT_SYMBOL_PATH", p, alt_sym_path_len);
|
||||||
|
p += alt_sym_path_len - 1;
|
||||||
|
}
|
||||||
|
*p = L'\0';
|
||||||
|
|
||||||
|
return search_path;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* SymSetSearchPathW (DBGHELP.@)
|
* SymSetSearchPathW (DBGHELP.@)
|
||||||
*
|
*
|
||||||
|
@ -198,14 +235,24 @@ struct cpu* cpu_find(DWORD machine)
|
||||||
BOOL WINAPI SymSetSearchPathW(HANDLE hProcess, PCWSTR searchPath)
|
BOOL WINAPI SymSetSearchPathW(HANDLE hProcess, PCWSTR searchPath)
|
||||||
{
|
{
|
||||||
struct process* pcs = process_find_by_handle(hProcess);
|
struct process* pcs = process_find_by_handle(hProcess);
|
||||||
|
WCHAR* search_path_buffer;
|
||||||
|
|
||||||
if (!pcs) return FALSE;
|
if (!pcs) return FALSE;
|
||||||
if (!searchPath) return FALSE;
|
|
||||||
|
|
||||||
|
if (searchPath)
|
||||||
|
{
|
||||||
|
search_path_buffer = HeapAlloc(GetProcessHeap(), 0,
|
||||||
|
(lstrlenW(searchPath) + 1) * sizeof(WCHAR));
|
||||||
|
if (!search_path_buffer) return FALSE;
|
||||||
|
lstrcpyW(search_path_buffer, searchPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
search_path_buffer = make_default_search_path();
|
||||||
|
if (!search_path_buffer) return FALSE;
|
||||||
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, pcs->search_path);
|
HeapFree(GetProcessHeap(), 0, pcs->search_path);
|
||||||
pcs->search_path = lstrcpyW(HeapAlloc(GetProcessHeap(), 0,
|
pcs->search_path = search_path_buffer;
|
||||||
(lstrlenW(searchPath) + 1) * sizeof(WCHAR)),
|
|
||||||
searchPath);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,16 +264,19 @@ BOOL WINAPI SymSetSearchPath(HANDLE hProcess, PCSTR searchPath)
|
||||||
{
|
{
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
unsigned len;
|
unsigned len;
|
||||||
WCHAR* sp;
|
WCHAR* sp = NULL;
|
||||||
|
|
||||||
len = MultiByteToWideChar(CP_ACP, 0, searchPath, -1, NULL, 0);
|
if (searchPath)
|
||||||
if ((sp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
|
|
||||||
{
|
{
|
||||||
|
len = MultiByteToWideChar(CP_ACP, 0, searchPath, -1, NULL, 0);
|
||||||
|
sp = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
||||||
|
if (!sp) return FALSE;
|
||||||
MultiByteToWideChar(CP_ACP, 0, searchPath, -1, sp, len);
|
MultiByteToWideChar(CP_ACP, 0, searchPath, -1, sp, len);
|
||||||
|
|
||||||
ret = SymSetSearchPathW(hProcess, sp);
|
|
||||||
HeapFree(GetProcessHeap(), 0, sp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = SymSetSearchPathW(hProcess, sp);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, sp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -448,31 +498,7 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned size;
|
pcs->search_path = make_default_search_path();
|
||||||
unsigned len;
|
|
||||||
static const WCHAR sym_path[] = {'_','N','T','_','S','Y','M','B','O','L','_','P','A','T','H',0};
|
|
||||||
static const WCHAR alt_sym_path[] = {'_','N','T','_','A','L','T','E','R','N','A','T','E','_','S','Y','M','B','O','L','_','P','A','T','H',0};
|
|
||||||
|
|
||||||
pcs->search_path = HeapAlloc(GetProcessHeap(), 0, (len = MAX_PATH) * sizeof(WCHAR));
|
|
||||||
while ((size = GetCurrentDirectoryW(len, pcs->search_path)) >= len)
|
|
||||||
pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (len *= 2) * sizeof(WCHAR));
|
|
||||||
pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (size + 1) * sizeof(WCHAR));
|
|
||||||
|
|
||||||
len = GetEnvironmentVariableW(sym_path, NULL, 0);
|
|
||||||
if (len)
|
|
||||||
{
|
|
||||||
pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (size + 1 + len + 1) * sizeof(WCHAR));
|
|
||||||
pcs->search_path[size] = ';';
|
|
||||||
GetEnvironmentVariableW(sym_path, pcs->search_path + size + 1, len);
|
|
||||||
size += 1 + len;
|
|
||||||
}
|
|
||||||
len = GetEnvironmentVariableW(alt_sym_path, NULL, 0);
|
|
||||||
if (len)
|
|
||||||
{
|
|
||||||
pcs->search_path = HeapReAlloc(GetProcessHeap(), 0, pcs->search_path, (size + 1 + len + 1) * sizeof(WCHAR));
|
|
||||||
pcs->search_path[size] = ';';
|
|
||||||
GetEnvironmentVariableW(alt_sym_path, pcs->search_path + size + 1, len);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pcs->lmodules = NULL;
|
pcs->lmodules = NULL;
|
||||||
|
|
|
@ -132,12 +132,77 @@ static void test_stack_walk(void)
|
||||||
|
|
||||||
#endif /* __i386__ || __x86_64__ */
|
#endif /* __i386__ || __x86_64__ */
|
||||||
|
|
||||||
|
static void test_search_path(void)
|
||||||
|
{
|
||||||
|
char search_path[128];
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
/* The default symbol path is ".[;%_NT_SYMBOL_PATH%][;%_NT_ALT_SYMBOL_PATH%]".
|
||||||
|
* We unset both variables earlier so should simply get "." */
|
||||||
|
ret = SymGetSearchPath(GetCurrentProcess(), search_path, ARRAY_SIZE(search_path));
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ok(!strcmp(search_path, "."), "Got search path '%s', expected '.'\n", search_path);
|
||||||
|
|
||||||
|
/* Set an arbitrary search path */
|
||||||
|
ret = SymSetSearchPath(GetCurrentProcess(), "W:\\");
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ret = SymGetSearchPath(GetCurrentProcess(), search_path, ARRAY_SIZE(search_path));
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ok(!strcmp(search_path, "W:\\"), "Got search path '%s', expected 'W:\\'\n", search_path);
|
||||||
|
|
||||||
|
/* Setting to NULL resets to the default */
|
||||||
|
ret = SymSetSearchPath(GetCurrentProcess(), NULL);
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ret = SymGetSearchPath(GetCurrentProcess(), search_path, ARRAY_SIZE(search_path));
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ok(!strcmp(search_path, "."), "Got search path '%s', expected '.'\n", search_path);
|
||||||
|
|
||||||
|
/* With _NT_SYMBOL_PATH */
|
||||||
|
SetEnvironmentVariableA("_NT_SYMBOL_PATH", "X:\\");
|
||||||
|
ret = SymSetSearchPath(GetCurrentProcess(), NULL);
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ret = SymGetSearchPath(GetCurrentProcess(), search_path, ARRAY_SIZE(search_path));
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ok(!strcmp(search_path, ".;X:\\"), "Got search path '%s', expected '.;X:\\'\n", search_path);
|
||||||
|
|
||||||
|
/* With both _NT_SYMBOL_PATH and _NT_ALT_SYMBOL_PATH */
|
||||||
|
SetEnvironmentVariableA("_NT_ALT_SYMBOL_PATH", "Y:\\");
|
||||||
|
ret = SymSetSearchPath(GetCurrentProcess(), NULL);
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ret = SymGetSearchPath(GetCurrentProcess(), search_path, ARRAY_SIZE(search_path));
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ok(!strcmp(search_path, ".;X:\\;Y:\\"), "Got search path '%s', expected '.;X:\\;Y:\\'\n", search_path);
|
||||||
|
|
||||||
|
/* With just _NT_ALT_SYMBOL_PATH */
|
||||||
|
SetEnvironmentVariableA("_NT_SYMBOL_PATH", NULL);
|
||||||
|
ret = SymSetSearchPath(GetCurrentProcess(), NULL);
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ret = SymGetSearchPath(GetCurrentProcess(), search_path, ARRAY_SIZE(search_path));
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ok(!strcmp(search_path, ".;Y:\\"), "Got search path '%s', expected '.;Y:\\'\n", search_path);
|
||||||
|
|
||||||
|
/* Restore original search path */
|
||||||
|
SetEnvironmentVariableA("_NT_ALT_SYMBOL_PATH", NULL);
|
||||||
|
ret = SymSetSearchPath(GetCurrentProcess(), NULL);
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ret = SymGetSearchPath(GetCurrentProcess(), search_path, ARRAY_SIZE(search_path));
|
||||||
|
ok(ret == TRUE, "ret = %d\n", ret);
|
||||||
|
ok(!strcmp(search_path, "."), "Got search path '%s', expected '.'\n", search_path);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(dbghelp)
|
START_TEST(dbghelp)
|
||||||
{
|
{
|
||||||
BOOL ret = SymInitialize(GetCurrentProcess(), NULL, TRUE);
|
BOOL ret;
|
||||||
|
|
||||||
|
/* Don't let the user's environment influence our symbol path */
|
||||||
|
SetEnvironmentVariableA("_NT_SYMBOL_PATH", NULL);
|
||||||
|
SetEnvironmentVariableA("_NT_ALT_SYMBOL_PATH", NULL);
|
||||||
|
|
||||||
|
ret = SymInitialize(GetCurrentProcess(), NULL, TRUE);
|
||||||
ok(ret, "got error %u\n", GetLastError());
|
ok(ret, "got error %u\n", GetLastError());
|
||||||
|
|
||||||
test_stack_walk();
|
test_stack_walk();
|
||||||
|
test_search_path();
|
||||||
|
|
||||||
ret = SymCleanup(GetCurrentProcess());
|
ret = SymCleanup(GetCurrentProcess());
|
||||||
ok(ret, "got error %u\n", GetLastError());
|
ok(ret, "got error %u\n", GetLastError());
|
||||||
|
|
Loading…
Reference in a new issue