mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
Merge branch 'upstream-KWSys' into update-kwsys
# By KWSys Upstream * upstream-KWSys: KWSys 2026-08-14 (f87534bd)
This commit is contained in:
@@ -3981,12 +3981,18 @@ std::string SystemInformationImplementation::GetProgramStack(int firstFrame,
|
||||
|
||||
void* stack[TRACE_MAX_STACK_FRAMES];
|
||||
HANDLE process = GetCurrentProcess();
|
||||
// SymSetOptions affects the process-global symbol handler options, so
|
||||
// save the caller's options and restore them before returning.
|
||||
DWORD options = SymGetOptions();
|
||||
SymSetOptions(options | SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS |
|
||||
SYMOPT_LOAD_LINES);
|
||||
SymInitialize(process, nullptr, TRUE);
|
||||
WORD numberOfFrames =
|
||||
CaptureStackBackTrace(firstFrame, TRACE_MAX_STACK_FRAMES, stack, nullptr);
|
||||
SYMBOL_INFO* symbol = static_cast<SYMBOL_INFO*>(
|
||||
malloc(sizeof(SYMBOL_INFO) +
|
||||
(TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR)));
|
||||
calloc(1,
|
||||
sizeof(SYMBOL_INFO) +
|
||||
(TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR)));
|
||||
symbol->MaxNameLen = TRACE_MAX_FUNCTION_NAME_LENGTH;
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
DWORD displacement;
|
||||
@@ -3994,15 +4000,59 @@ std::string SystemInformationImplementation::GetProgramStack(int firstFrame,
|
||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
for (int i = 0; i < numberOfFrames; i++) {
|
||||
DWORD64 address = reinterpret_cast<DWORD64>(stack[i]);
|
||||
SymFromAddr(process, address, nullptr, symbol);
|
||||
if (SymGetLineFromAddr64(process, address, &displacement, &line)) {
|
||||
DWORD64 symDisplacement = 0;
|
||||
bool haveName =
|
||||
SymFromAddr(process, address, &symDisplacement, symbol) != FALSE;
|
||||
DWORD64 moduleBase = SymGetModuleBase64(process, address);
|
||||
// When a module has no matching PDB, dbghelp falls back to its export
|
||||
// table and reports the nearest preceding export, which is generally not
|
||||
// the (non-exported) function the address really belongs to. Names are
|
||||
// only exact when real debug info was loaded for the module, so ask the
|
||||
// module how its symbols were obtained rather than trusting the name.
|
||||
// Inexact names are still printed, but marked and always accompanied by
|
||||
// the module-relative address so they cannot be mistaken for the truth.
|
||||
bool exactName = haveName;
|
||||
if (exactName) {
|
||||
IMAGEHLP_MODULE64 moduleInfo;
|
||||
memset(&moduleInfo, 0, sizeof(moduleInfo));
|
||||
moduleInfo.SizeOfStruct = sizeof(moduleInfo);
|
||||
if (!SymGetModuleInfo64(process, address, &moduleInfo) ||
|
||||
moduleInfo.SymType == SymNone || moduleInfo.SymType == SymExport ||
|
||||
moduleInfo.SymType == SymDeferred) {
|
||||
exactName = false;
|
||||
}
|
||||
}
|
||||
if (exactName &&
|
||||
SymGetLineFromAddr64(process, address, &displacement, &line)) {
|
||||
oss << " at " << symbol->Name << " in " << line.FileName << " line "
|
||||
<< line.LineNumber << std::endl;
|
||||
} else if (exactName) {
|
||||
oss << " at " << symbol->Name << "+0x" << std::hex << symDisplacement
|
||||
<< std::dec << std::endl;
|
||||
} else {
|
||||
oss << " at " << symbol->Name << std::endl;
|
||||
// Report the module containing the address together with the offset
|
||||
// into that module, which is what a disassembler needs, plus the
|
||||
// nearest export as an approximate location hint when one is known.
|
||||
wchar_t modulePath[MAX_PATH];
|
||||
DWORD64 moduleBase = SymGetModuleBase64(process, address);
|
||||
if (moduleBase &&
|
||||
GetModuleFileNameW(reinterpret_cast<HMODULE>(moduleBase), modulePath,
|
||||
MAX_PATH) > 0) {
|
||||
oss << " at " << modulePath << "+0x" << std::hex
|
||||
<< (address - moduleBase) << std::dec;
|
||||
} else {
|
||||
oss << " at 0x" << std::hex << address << std::dec;
|
||||
}
|
||||
if (haveName) {
|
||||
oss << " (near " << symbol->Name << "+0x" << std::hex
|
||||
<< symDisplacement << std::dec << ")";
|
||||
}
|
||||
oss << std::endl;
|
||||
}
|
||||
}
|
||||
free(symbol);
|
||||
SymSetOptions(options);
|
||||
SymCleanup(process);
|
||||
|
||||
#else
|
||||
programStack += ""
|
||||
|
||||
@@ -298,7 +298,7 @@ static time_t windows_filetime_to_posix_time(const FILETIME& ft)
|
||||
typedef KWSYS_NAMESPACE::SystemTools::mode_t mode_t;
|
||||
# endif
|
||||
|
||||
inline int Mkdir(std::string const& dir, mode_t const* mode)
|
||||
static inline int Mkdir(std::string const& dir, mode_t const* mode)
|
||||
{
|
||||
int ret =
|
||||
_wmkdir(KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
|
||||
@@ -306,12 +306,12 @@ inline int Mkdir(std::string const& dir, mode_t const* mode)
|
||||
KWSYS_NAMESPACE::SystemTools::SetPermissions(dir, *mode);
|
||||
return ret;
|
||||
}
|
||||
inline int Rmdir(std::string const& dir)
|
||||
static inline int Rmdir(std::string const& dir)
|
||||
{
|
||||
return _wrmdir(
|
||||
KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
|
||||
}
|
||||
inline char const* Getcwd(char* buf, unsigned int len)
|
||||
static inline char const* Getcwd(char* buf, unsigned int len)
|
||||
{
|
||||
std::vector<wchar_t> w_buf(len);
|
||||
if (_wgetcwd(&w_buf[0], len)) {
|
||||
@@ -329,15 +329,16 @@ inline char const* Getcwd(char* buf, unsigned int len)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
inline int Chdir(std::string const& dir)
|
||||
static inline int Chdir(std::string const& dir)
|
||||
{
|
||||
// We cannot use ToWindowsExtendedPath here because that causes a
|
||||
// UNC path to be recorded as the process working directory, and
|
||||
// can break child processes.
|
||||
return _wchdir(KWSYS_NAMESPACE::Encoding::ToWide(dir).c_str());
|
||||
}
|
||||
inline void Realpath(std::string const& path, std::string& resolved_path,
|
||||
std::string* errorMessage = nullptr)
|
||||
static inline void Realpath(std::string const& path,
|
||||
std::string& resolved_path,
|
||||
std::string* errorMessage = nullptr)
|
||||
{
|
||||
std::wstring tmp = KWSYS_NAMESPACE::Encoding::ToWide(path);
|
||||
wchar_t fullpath[MAX_PATH];
|
||||
@@ -372,25 +373,26 @@ inline void Realpath(std::string const& path, std::string& resolved_path,
|
||||
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
inline int Mkdir(std::string const& dir, mode_t const* mode)
|
||||
static inline int Mkdir(std::string const& dir, mode_t const* mode)
|
||||
{
|
||||
return mkdir(dir.c_str(), mode ? *mode : 00777);
|
||||
}
|
||||
inline int Rmdir(std::string const& dir)
|
||||
static inline int Rmdir(std::string const& dir)
|
||||
{
|
||||
return rmdir(dir.c_str());
|
||||
}
|
||||
inline char const* Getcwd(char* buf, unsigned int len)
|
||||
static inline char const* Getcwd(char* buf, unsigned int len)
|
||||
{
|
||||
return getcwd(buf, len);
|
||||
}
|
||||
|
||||
inline int Chdir(std::string const& dir)
|
||||
static inline int Chdir(std::string const& dir)
|
||||
{
|
||||
return chdir(dir.c_str());
|
||||
}
|
||||
inline void Realpath(std::string const& path, std::string& resolved_path,
|
||||
std::string* errorMessage = nullptr)
|
||||
static inline void Realpath(std::string const& path,
|
||||
std::string& resolved_path,
|
||||
std::string* errorMessage = nullptr)
|
||||
{
|
||||
char resolved_name[KWSYS_SYSTEMTOOLS_MAXPATH];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user