mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-18 01:34:14 +08:00
3eddddcf23
This patch implements a stack trace for a thread, not unlike sysrq-t does. The advantage to this is that a break point can be placed on showreqs, so that upon showing the stack, you jump immediately into the debugger. While sysrq-t does the same thing, sysrq-t shows *all* threads stacks. It also doesn't work right now. In the future, I thought it might be acceptable to make this show all pids stacks, but perhaps leaving well enough alone and just using sysrq-t would be okay. For now, upon receiving the stack command, UML switches context to that thread, dumps its registers, and then switches context back to the original thread. Since UML compacts all threads into one of 4 host threads, this sort of mechanism could be expanded in the future to include other debugging helpers that sysrq does not cover. Note by jdike - The main benefit to this is that it brings an arbitrary thread back into context, where it can be examined by gdb. The fact that it dumps it stack is secondary. This provides the capability to examine a sleeping thread, which has existed in tt mode, but not in skas mode until now. Also, the other threads, that sysrq doesn't cover, can be gdb-ed directly anyway. Signed-off-by: Allan Graves<allan.graves@gmail.com> Signed-off-by: Jeff Dike <jdike@addtoit.com> Cc: Paolo Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
105 lines
2.5 KiB
C
105 lines
2.5 KiB
C
/*
|
|
* Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
|
|
* Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
|
|
* Licensed under the GPL
|
|
*/
|
|
|
|
#ifndef __MCONSOLE_H__
|
|
#define __MCONSOLE_H__
|
|
|
|
#ifndef __KERNEL__
|
|
#include <stdint.h>
|
|
#define u32 uint32_t
|
|
#endif
|
|
|
|
#define MCONSOLE_MAGIC (0xcafebabe)
|
|
#define MCONSOLE_MAX_DATA (512)
|
|
#define MCONSOLE_VERSION 2
|
|
|
|
struct mconsole_request {
|
|
u32 magic;
|
|
u32 version;
|
|
u32 len;
|
|
char data[MCONSOLE_MAX_DATA];
|
|
};
|
|
|
|
struct mconsole_reply {
|
|
u32 err;
|
|
u32 more;
|
|
u32 len;
|
|
char data[MCONSOLE_MAX_DATA];
|
|
};
|
|
|
|
struct mconsole_notify {
|
|
u32 magic;
|
|
u32 version;
|
|
enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
|
|
MCONSOLE_USER_NOTIFY } type;
|
|
u32 len;
|
|
char data[MCONSOLE_MAX_DATA];
|
|
};
|
|
|
|
struct mc_request;
|
|
|
|
enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
|
|
|
|
struct mconsole_command
|
|
{
|
|
char *command;
|
|
void (*handler)(struct mc_request *req);
|
|
enum mc_context context;
|
|
};
|
|
|
|
struct mc_request
|
|
{
|
|
int len;
|
|
int as_interrupt;
|
|
|
|
int originating_fd;
|
|
unsigned int originlen;
|
|
unsigned char origin[128]; /* sockaddr_un */
|
|
|
|
struct mconsole_request request;
|
|
struct mconsole_command *cmd;
|
|
};
|
|
|
|
extern char mconsole_socket_name[];
|
|
|
|
extern int mconsole_unlink_socket(void);
|
|
extern int mconsole_reply(struct mc_request *req, char *reply, int err,
|
|
int more);
|
|
|
|
extern void mconsole_version(struct mc_request *req);
|
|
extern void mconsole_help(struct mc_request *req);
|
|
extern void mconsole_halt(struct mc_request *req);
|
|
extern void mconsole_reboot(struct mc_request *req);
|
|
extern void mconsole_config(struct mc_request *req);
|
|
extern void mconsole_remove(struct mc_request *req);
|
|
extern void mconsole_sysrq(struct mc_request *req);
|
|
extern void mconsole_cad(struct mc_request *req);
|
|
extern void mconsole_stop(struct mc_request *req);
|
|
extern void mconsole_go(struct mc_request *req);
|
|
extern void mconsole_log(struct mc_request *req);
|
|
extern void mconsole_proc(struct mc_request *req);
|
|
extern void mconsole_stack(struct mc_request *req);
|
|
|
|
extern int mconsole_get_request(int fd, struct mc_request *req);
|
|
extern int mconsole_notify(char *sock_name, int type, const void *data,
|
|
int len);
|
|
extern char *mconsole_notify_socket(void);
|
|
extern void lock_notify(void);
|
|
extern void unlock_notify(void);
|
|
|
|
#endif
|
|
|
|
/*
|
|
* Overrides for Emacs so that we follow Linus's tabbing style.
|
|
* Emacs will notice this stuff at the end of the file and automatically
|
|
* adjust the settings for this buffer only. This must remain at the end
|
|
* of the file.
|
|
* ---------------------------------------------------------------------------
|
|
* Local variables:
|
|
* c-file-style: "linux"
|
|
* End:
|
|
*/
|