kerneldump: Inline dump_savectx() into its callers
The callers of dump_savectx() (i.e., doadump() and livedump_start())
subsequently call dumpsys()/minidumpsys(), which dump the calling
thread's stack when writing the dump. If dump_savectx() gets its own
stack frame, that frame might be clobbered when its caller later calls
dumpsys()/minidumpsys(), making it difficult for debuggers to unwind the
stack.
Fix this by making dump_savectx() a macro, so that savectx() is always
called directly by the function which subsequently calls
dumpsys()/minidumpsys().
This fixes stack unwinding for the panicking thread from arm64
minidumps. The same happened to work on amd64, but kgdb reports the
dump_savectx() calls as coming from dumpsys(), so in that case it
appears to work by accident.
Fixes: c9114f9f86
("Add new vnode dumper to support live minidumps")
Reviewed by: mhorne, jhb
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D39151
This commit is contained in:
parent
3ce64010f8
commit
c3179891f8
@ -244,8 +244,8 @@ MTX_SYSINIT(dumper_configs, &dumpconf_list_lk, "dumper config list", MTX_DEF);
|
||||
static TAILQ_HEAD(dumpconflist, dumperinfo) dumper_configs =
|
||||
TAILQ_HEAD_INITIALIZER(dumper_configs);
|
||||
|
||||
/* Context information for dump-debuggers. */
|
||||
static struct pcb dumppcb; /* Registers. */
|
||||
/* Context information for dump-debuggers, saved by the dump_savectx() macro. */
|
||||
struct pcb dumppcb; /* Registers. */
|
||||
lwpid_t dumptid; /* Thread ID. */
|
||||
|
||||
static struct cdevsw reroot_cdevsw = {
|
||||
@ -392,17 +392,6 @@ print_uptime(void)
|
||||
printf("%lds\n", (long)ts.tv_sec);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a context that can be extracted from the dump.
|
||||
*/
|
||||
void
|
||||
dump_savectx(void)
|
||||
{
|
||||
|
||||
savectx(&dumppcb);
|
||||
dumptid = curthread->td_tid;
|
||||
}
|
||||
|
||||
int
|
||||
doadump(boolean_t textdump)
|
||||
{
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/vmparam.h>
|
||||
|
||||
static dumper_start_t vnode_dumper_start;
|
||||
|
@ -360,7 +360,21 @@ struct dumperinfo {
|
||||
|
||||
extern int dumping; /* system is dumping */
|
||||
|
||||
void dump_savectx(void);
|
||||
/*
|
||||
* Save registers for later extraction from a kernel dump.
|
||||
*
|
||||
* This must be inlined into the caller, which in turn must be the function that
|
||||
* calls (mini)dumpsys(). Otherwise, the saved frame pointer will reference a
|
||||
* stack frame that may be clobbered by subsequent function calls.
|
||||
*/
|
||||
#define dump_savectx() do { \
|
||||
extern struct pcb dumppcb; \
|
||||
extern lwpid_t dumptid; \
|
||||
\
|
||||
savectx(&dumppcb); \
|
||||
dumptid = curthread->td_tid; \
|
||||
} while (0)
|
||||
|
||||
int doadump(boolean_t);
|
||||
struct diocskerneldump_arg;
|
||||
int dumper_create(const struct dumperinfo *di_template, const char *devname,
|
||||
|
Loading…
Reference in New Issue
Block a user