ectx_find() failed to lookup the emulation context unless it happened
to be the first entry, effectively resetting context of all processes to default emulation on every EMUL trace record rewrite ectx_find() to fix this, using <sys/queue.h> LIST for readability this fix should once and for all remove need to ever use -e option, and makes kdump work properly for traces with processes under different emulations
This commit is contained in:
parent
82318e9375
commit
04fa39a4be
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: setemul.c,v 1.19 2004/01/12 13:39:56 mrg Exp $ */
|
/* $NetBSD: setemul.c,v 1.20 2005/01/15 17:55:38 jdolecek Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||||
|
@ -69,12 +69,13 @@
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
__RCSID("$NetBSD: setemul.c,v 1.19 2004/01/12 13:39:56 mrg Exp $");
|
__RCSID("$NetBSD: setemul.c,v 1.20 2005/01/15 17:55:38 jdolecek Exp $");
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/errno.h>
|
#include <sys/errno.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/queue.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -235,7 +236,7 @@ const struct emulation emulations[] = {
|
||||||
struct emulation_ctx {
|
struct emulation_ctx {
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
const struct emulation *emulation;
|
const struct emulation *emulation;
|
||||||
struct emulation_ctx *next;
|
LIST_ENTRY(emulation_ctx) ctx_link;
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct emulation *cur_emul;
|
const struct emulation *cur_emul;
|
||||||
|
@ -248,8 +249,8 @@ static const struct emulation *mach_fasttraps;
|
||||||
static const struct emulation *default_emul = &emulations[0];
|
static const struct emulation *default_emul = &emulations[0];
|
||||||
|
|
||||||
struct emulation_ctx *current_ctx;
|
struct emulation_ctx *current_ctx;
|
||||||
static struct emulation_ctx emul_0 = {0, &emulations[0], NULL};
|
static LIST_HEAD(, emulation_ctx) emul_ctx =
|
||||||
struct emulation_ctx *emul_ctx = &emul_0;
|
LIST_HEAD_INITIALIZER(emul_ctx);
|
||||||
|
|
||||||
static struct emulation_ctx *ectx_find(pid_t);
|
static struct emulation_ctx *ectx_find(pid_t);
|
||||||
static void ectx_update(pid_t, const struct emulation *);
|
static void ectx_update(pid_t, const struct emulation *);
|
||||||
|
@ -300,31 +301,30 @@ setemul(const char *name, pid_t pid, int update_ectx)
|
||||||
static struct emulation_ctx *
|
static struct emulation_ctx *
|
||||||
ectx_find(pid_t pid)
|
ectx_find(pid_t pid)
|
||||||
{
|
{
|
||||||
struct emulation_ctx *ctx, **pctx;
|
struct emulation_ctx *ctx;
|
||||||
|
|
||||||
/* Top of list is almost always right... (and list is never empty) */
|
/* Find an existing entry */
|
||||||
if (emul_ctx->pid == pid)
|
LIST_FOREACH(ctx, &emul_ctx, ctx_link) {
|
||||||
return emul_ctx;
|
if (ctx->pid == pid)
|
||||||
|
|
||||||
for (pctx = &emul_ctx; ; pctx = &ctx->next) {
|
|
||||||
ctx = *pctx;
|
|
||||||
if (ctx == NULL) {
|
|
||||||
/* create entry with default emulation */
|
|
||||||
ctx = malloc(sizeof *ctx);
|
|
||||||
if (ctx == NULL)
|
|
||||||
err(1, "malloc emul context");
|
|
||||||
ctx->pid = pid;
|
|
||||||
ctx->emulation = default_emul;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (ctx->pid != pid)
|
|
||||||
continue;
|
|
||||||
/* Cut out of chain */
|
|
||||||
*pctx = ctx->next;
|
|
||||||
}
|
}
|
||||||
/* Add at chain head */
|
|
||||||
ctx->next = emul_ctx;
|
if (ctx == NULL) {
|
||||||
emul_ctx = ctx;
|
/* create entry with default emulation */
|
||||||
|
ctx = malloc(sizeof *ctx);
|
||||||
|
if (ctx == NULL)
|
||||||
|
err(1, "malloc emul context");
|
||||||
|
ctx->pid = pid;
|
||||||
|
ctx->emulation = default_emul;
|
||||||
|
|
||||||
|
/* chain into the list */
|
||||||
|
LIST_INSERT_HEAD(&emul_ctx, ctx, ctx_link);
|
||||||
|
} else {
|
||||||
|
/* move entry to head to optimize lookup for syscall bursts */
|
||||||
|
LIST_REMOVE(ctx, ctx_link);
|
||||||
|
LIST_INSERT_HEAD(&emul_ctx, ctx, ctx_link);
|
||||||
|
}
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,20 +361,19 @@ ectx_sanify(pid_t pid)
|
||||||
void
|
void
|
||||||
ectx_delete(void)
|
ectx_delete(void)
|
||||||
{
|
{
|
||||||
static struct emulation_ctx *ctx;
|
static struct emulation_ctx *ctx = NULL;
|
||||||
struct emulation_ctx *nctx;
|
|
||||||
|
|
||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
free(ctx);
|
free(ctx);
|
||||||
|
|
||||||
nctx = emul_ctx->next;
|
/*
|
||||||
if (nctx == NULL) {
|
* The emulation for current syscall entry is always on HEAD, due
|
||||||
/* sanity - last item on list should never be killed */
|
* to code in ectx_find().
|
||||||
ctx = NULL;
|
*/
|
||||||
return;
|
ctx = LIST_FIRST(&emul_ctx);
|
||||||
}
|
|
||||||
ctx = emul_ctx;
|
if (ctx)
|
||||||
emul_ctx = nctx;
|
LIST_REMOVE(ctx, ctx_link);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue