f31522130f
Build system (5 gaps hardened): - COOKBOOK_OFFLINE defaults to true (fork-mode) - normalize_patch handles diff -ruN format - New 'repo validate-patches' command (25/25 relibc patches) - 14 patched Qt/Wayland/display recipes added to protected list - relibc archive regenerated with current patch chain Boot fixes (fixable): - Full ISO EFI partition: 16 MiB → 1 MiB (matches mini, BIOS hardcoded 2 MiB offset) - D-Bus system bus: absolute /usr/bin/dbus-daemon path (was skipped) - redbear-sessiond: absolute /usr/bin/redbear-sessiond path (was skipped) - daemon framework: silenced spurious INIT_NOTIFY warnings for oneshot_async services (P0-daemon-silence-init-notify.patch) - udev-shim: demoted INIT_NOTIFY warning to INFO (expected for oneshot_async) - relibc: comprehensive named semaphores (sem_open/close/unlink) replacing upstream todo!() stubs - greeterd: Wayland socket timeout 15s → 30s (compositor DRM wait) - greeter-ui: built and linked (header guard unification, sem_compat stubs removed) - mc: un-ignored in both configs, fixed glib/libiconv/pcre2 transitive deps - greeter config: removed stale keymapd dependency from display/greeter services - prefix toolchain: relibc headers synced, _RELIBC_STDLIB_H guard unified Unfixable (diagnosed, upstream): - i2c-hidd: abort on no-I2C-hardware (QEMU) — process::exit → relibc abort - kded6/greeter-ui: page fault 0x8 — Qt library null deref - Thread panics fd != -1 — Rust std library on Redox - DHCP timeout / eth0 MAC — QEMU user-mode networking - hwrngd/thermald — no hardware RNG/thermal in VM - live preload allocation — BIOS memory fragmentation, continues on demand
214 lines
6.2 KiB
C
214 lines
6.2 KiB
C
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
/* dbus-backtrace-win.c Backtrace Generator
|
|
*
|
|
* Copyright 2004 Eric Poech
|
|
* Copyright 2004 Robert Shearman
|
|
* Copyright 2010 Patrick von Reth <patrick.vonreth@gmail.com>
|
|
* Copyright 2015 Ralf Habacker <ralf.habacker@freenet.de>
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include "dbus-internals.h"
|
|
#include "dbus-sysdeps.h"
|
|
|
|
#if !defined (DBUS_DISABLE_ASSERT) || defined(DBUS_ENABLE_EMBEDDED_TESTS)
|
|
|
|
#if defined(_MSC_VER) || defined(DBUS_WINCE)
|
|
# ifdef BACKTRACES
|
|
# undef BACKTRACES
|
|
# endif
|
|
#else
|
|
# define BACKTRACES
|
|
#endif
|
|
|
|
#ifdef BACKTRACES
|
|
#include "dbus-sysdeps-win.h"
|
|
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
#include <imagehlp.h>
|
|
|
|
#define DPRINTF(fmt, ...) fprintf (stderr, fmt, ##__VA_ARGS__)
|
|
|
|
#ifdef _MSC_VER
|
|
#define BOOL int
|
|
|
|
#define __i386__
|
|
#endif
|
|
|
|
static void dump_backtrace_for_thread (HANDLE hThread)
|
|
{
|
|
ADDRESS old_address;
|
|
STACKFRAME sf;
|
|
CONTEXT context;
|
|
DWORD dwImageType;
|
|
int i = 0;
|
|
|
|
SymSetOptions (SYMOPT_UNDNAME | SYMOPT_LOAD_LINES);
|
|
SymInitialize (GetCurrentProcess (), NULL, TRUE);
|
|
|
|
|
|
/* can't use this function for current thread as GetThreadContext
|
|
* doesn't support getting context from current thread */
|
|
if (hThread == GetCurrentThread())
|
|
return;
|
|
|
|
DPRINTF ("Backtrace:\n");
|
|
|
|
_DBUS_ZERO (old_address);
|
|
_DBUS_ZERO (context);
|
|
context.ContextFlags = CONTEXT_FULL;
|
|
|
|
SuspendThread (hThread);
|
|
|
|
if (!GetThreadContext (hThread, &context))
|
|
{
|
|
DPRINTF ("Couldn't get thread context (error %ld)\n", GetLastError ());
|
|
ResumeThread (hThread);
|
|
return;
|
|
}
|
|
|
|
_DBUS_ZERO (sf);
|
|
|
|
#ifdef __i386__
|
|
dwImageType = IMAGE_FILE_MACHINE_I386;
|
|
sf.AddrFrame.Offset = context.Ebp;
|
|
sf.AddrFrame.Mode = AddrModeFlat;
|
|
sf.AddrPC.Offset = context.Eip;
|
|
sf.AddrPC.Mode = AddrModeFlat;
|
|
#elif defined(_M_X64)
|
|
dwImageType = IMAGE_FILE_MACHINE_AMD64;
|
|
sf.AddrPC.Offset = context.Rip;
|
|
sf.AddrPC.Mode = AddrModeFlat;
|
|
sf.AddrFrame.Offset = context.Rsp;
|
|
sf.AddrFrame.Mode = AddrModeFlat;
|
|
sf.AddrStack.Offset = context.Rsp;
|
|
sf.AddrStack.Mode = AddrModeFlat;
|
|
#elif defined(_M_IA64)
|
|
dwImageType = IMAGE_FILE_MACHINE_IA64;
|
|
sf.AddrPC.Offset = context.StIIP;
|
|
sf.AddrPC.Mode = AddrModeFlat;
|
|
sf.AddrFrame.Offset = context.IntSp;
|
|
sf.AddrFrame.Mode = AddrModeFlat;
|
|
sf.AddrBStore.Offset= context.RsBSP;
|
|
sf.AddrBStore.Mode = AddrModeFlat;
|
|
sf.AddrStack.Offset = context.IntSp;
|
|
sf.AddrStack.Mode = AddrModeFlat;
|
|
#else
|
|
# error You need to fill in the STACKFRAME structure for your architecture
|
|
#endif
|
|
|
|
/*
|
|
backtrace format
|
|
<level> <address> <symbol>[+offset] [ '[' <file> ':' <line> ']' ] [ 'in' <module> ]
|
|
example:
|
|
6 0xf75ade6b wine_switch_to_stack+0x2a [/usr/src/debug/wine-snapshot/libs/wine/port.c:59] in libwine.so.1
|
|
*/
|
|
while (StackWalk (dwImageType, GetCurrentProcess (),
|
|
hThread, &sf, &context, NULL, SymFunctionTableAccess,
|
|
SymGetModuleBase, NULL))
|
|
{
|
|
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)];
|
|
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
|
DWORD64 displacement;
|
|
IMAGEHLP_LINE line;
|
|
DWORD dwDisplacement;
|
|
IMAGEHLP_MODULE moduleInfo;
|
|
|
|
/*
|
|
on Wine64 version 1.7.54, we get an infinite number of stack entries
|
|
pointing to the same stack frame (_start+0x29 in <wine-loader>)
|
|
see bug https://bugs.winehq.org/show_bug.cgi?id=39606
|
|
*/
|
|
#ifndef __i386__
|
|
if (old_address.Offset == sf.AddrPC.Offset)
|
|
{
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
|
pSymbol->MaxNameLen = MAX_SYM_NAME;
|
|
|
|
if (SymFromAddr (GetCurrentProcess (), sf.AddrPC.Offset, &displacement, pSymbol))
|
|
{
|
|
if (displacement)
|
|
DPRINTF ("%3d %s+0x%I64x", i++, pSymbol->Name, displacement);
|
|
else
|
|
DPRINTF ("%3d %s", i++, pSymbol->Name);
|
|
}
|
|
else
|
|
DPRINTF ("%3d 0x%Ix", i++, sf.AddrPC.Offset);
|
|
|
|
line.SizeOfStruct = sizeof(IMAGEHLP_LINE);
|
|
if (SymGetLineFromAddr (GetCurrentProcess (), sf.AddrPC.Offset, &dwDisplacement, &line))
|
|
{
|
|
DPRINTF (" [%s:%ld]", line.FileName, line.LineNumber);
|
|
}
|
|
|
|
moduleInfo.SizeOfStruct = sizeof(moduleInfo);
|
|
if (SymGetModuleInfo (GetCurrentProcess (), sf.AddrPC.Offset, &moduleInfo))
|
|
{
|
|
DPRINTF (" in %s", moduleInfo.ModuleName);
|
|
}
|
|
DPRINTF ("\n");
|
|
old_address = sf.AddrPC;
|
|
}
|
|
ResumeThread (hThread);
|
|
}
|
|
|
|
static DWORD WINAPI dump_thread_proc (LPVOID lpParameter)
|
|
{
|
|
dump_backtrace_for_thread ((HANDLE) lpParameter);
|
|
return 0;
|
|
}
|
|
|
|
/* cannot get valid context from current thread, so we have to execute
|
|
* backtrace from another thread */
|
|
static void
|
|
dump_backtrace (void)
|
|
{
|
|
HANDLE hCurrentThread;
|
|
HANDLE hThread;
|
|
DWORD dwThreadId;
|
|
DuplicateHandle (GetCurrentProcess (), GetCurrentThread (),
|
|
GetCurrentProcess (), &hCurrentThread,
|
|
0, FALSE, DUPLICATE_SAME_ACCESS);
|
|
hThread = CreateThread (NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread,
|
|
0, &dwThreadId);
|
|
WaitForSingleObject (hThread, INFINITE);
|
|
CloseHandle (hThread);
|
|
CloseHandle (hCurrentThread);
|
|
}
|
|
#endif
|
|
#endif /* asserts or tests enabled */
|
|
|
|
#ifdef BACKTRACES
|
|
void _dbus_print_backtrace (void)
|
|
{
|
|
dump_backtrace ();
|
|
}
|
|
#else
|
|
void _dbus_print_backtrace (void)
|
|
{
|
|
_dbus_verbose (" D-Bus not compiled with backtrace support\n");
|
|
}
|
|
#endif
|