trace.h revision 929bd57ca202fd2f2e8485ebf65d683e664f67b5
19282254e29896366ea354b930b06f9defebbd041Petr Machata/*
29282254e29896366ea354b930b06f9defebbd041Petr Machata * This file is part of ltrace.
39282254e29896366ea354b930b06f9defebbd041Petr Machata * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
49282254e29896366ea354b930b06f9defebbd041Petr Machata *
59282254e29896366ea354b930b06f9defebbd041Petr Machata * This program is free software; you can redistribute it and/or
69282254e29896366ea354b930b06f9defebbd041Petr Machata * modify it under the terms of the GNU General Public License as
79282254e29896366ea354b930b06f9defebbd041Petr Machata * published by the Free Software Foundation; either version 2 of the
89282254e29896366ea354b930b06f9defebbd041Petr Machata * License, or (at your option) any later version.
99282254e29896366ea354b930b06f9defebbd041Petr Machata *
109282254e29896366ea354b930b06f9defebbd041Petr Machata * This program is distributed in the hope that it will be useful, but
119282254e29896366ea354b930b06f9defebbd041Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of
129282254e29896366ea354b930b06f9defebbd041Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
139282254e29896366ea354b930b06f9defebbd041Petr Machata * General Public License for more details.
149282254e29896366ea354b930b06f9defebbd041Petr Machata *
159282254e29896366ea354b930b06f9defebbd041Petr Machata * You should have received a copy of the GNU General Public License
169282254e29896366ea354b930b06f9defebbd041Petr Machata * along with this program; if not, write to the Free Software
179282254e29896366ea354b930b06f9defebbd041Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
189282254e29896366ea354b930b06f9defebbd041Petr Machata * 02110-1301 USA
199282254e29896366ea354b930b06f9defebbd041Petr Machata */
209282254e29896366ea354b930b06f9defebbd041Petr Machata
219282254e29896366ea354b930b06f9defebbd041Petr Machata#ifndef _LTRACE_LINUX_TRACE_H_
229282254e29896366ea354b930b06f9defebbd041Petr Machata#define _LTRACE_LINUX_TRACE_H_
239282254e29896366ea354b930b06f9defebbd041Petr Machata
24ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "proc.h"
25ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata
269282254e29896366ea354b930b06f9defebbd041Petr Machata/* This publishes some Linux-specific data structures used for process
279282254e29896366ea354b930b06f9defebbd041Petr Machata * handling.  */
289282254e29896366ea354b930b06f9defebbd041Petr Machata
299282254e29896366ea354b930b06f9defebbd041Petr Machata/**
309282254e29896366ea354b930b06f9defebbd041Petr Machata * This is used for bookkeeping related to PIDs that the event
319282254e29896366ea354b930b06f9defebbd041Petr Machata * handlers work with.
329282254e29896366ea354b930b06f9defebbd041Petr Machata */
339282254e29896366ea354b930b06f9defebbd041Petr Machatastruct pid_task {
349282254e29896366ea354b930b06f9defebbd041Petr Machata	pid_t pid;	/* This may be 0 for tasks that exited
359282254e29896366ea354b930b06f9defebbd041Petr Machata			 * mid-handling.  */
369282254e29896366ea354b930b06f9defebbd041Petr Machata	int sigstopped : 1;
379282254e29896366ea354b930b06f9defebbd041Petr Machata	int got_event : 1;
389282254e29896366ea354b930b06f9defebbd041Petr Machata	int delivered : 1;
399282254e29896366ea354b930b06f9defebbd041Petr Machata	int vforked : 1;
409282254e29896366ea354b930b06f9defebbd041Petr Machata	int sysret : 1;
419282254e29896366ea354b930b06f9defebbd041Petr Machata};
429282254e29896366ea354b930b06f9defebbd041Petr Machata
439282254e29896366ea354b930b06f9defebbd041Petr Machatastruct pid_set {
449282254e29896366ea354b930b06f9defebbd041Petr Machata	struct pid_task *tasks;
459282254e29896366ea354b930b06f9defebbd041Petr Machata	size_t count;
469282254e29896366ea354b930b06f9defebbd041Petr Machata	size_t alloc;
479282254e29896366ea354b930b06f9defebbd041Petr Machata};
489282254e29896366ea354b930b06f9defebbd041Petr Machata
499282254e29896366ea354b930b06f9defebbd041Petr Machata/**
509282254e29896366ea354b930b06f9defebbd041Petr Machata * Breakpoint re-enablement.  When we hit a breakpoint, we must
519282254e29896366ea354b930b06f9defebbd041Petr Machata * disable it, single-step, and re-enable it.  That single-step can be
529282254e29896366ea354b930b06f9defebbd041Petr Machata * done only by one task in a task group, while others are stopped,
539282254e29896366ea354b930b06f9defebbd041Petr Machata * otherwise the processes would race for who sees the breakpoint
549282254e29896366ea354b930b06f9defebbd041Petr Machata * disabled and who doesn't.  The following is to keep track of it
559282254e29896366ea354b930b06f9defebbd041Petr Machata * all.
569282254e29896366ea354b930b06f9defebbd041Petr Machata */
579282254e29896366ea354b930b06f9defebbd041Petr Machatastruct process_stopping_handler
589282254e29896366ea354b930b06f9defebbd041Petr Machata{
599282254e29896366ea354b930b06f9defebbd041Petr Machata	struct event_handler super;
609282254e29896366ea354b930b06f9defebbd041Petr Machata
619282254e29896366ea354b930b06f9defebbd041Petr Machata	/* The task that is doing the re-enablement.  */
62929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata	struct process *task_enabling_breakpoint;
639282254e29896366ea354b930b06f9defebbd041Petr Machata
649282254e29896366ea354b930b06f9defebbd041Petr Machata	/* The pointer being re-enabled.  */
659282254e29896366ea354b930b06f9defebbd041Petr Machata	struct breakpoint *breakpoint_being_enabled;
669282254e29896366ea354b930b06f9defebbd041Petr Machata
679282254e29896366ea354b930b06f9defebbd041Petr Machata	/* Artificial atomic skip breakpoint, if any needed.  */
6842748aca73359c83881556c8b28f6cda4f1c143bPetr Machata	void *atomic_skip_bp_addrs[2];
699282254e29896366ea354b930b06f9defebbd041Petr Machata
709282254e29896366ea354b930b06f9defebbd041Petr Machata	/* When all tasks are stopped, this callback gets called.  */
719282254e29896366ea354b930b06f9defebbd041Petr Machata	void (*on_all_stopped)(struct process_stopping_handler *);
729282254e29896366ea354b930b06f9defebbd041Petr Machata
7336f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata	/* When we get a singlestep event, this is called to decide
7436f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata	 * whether to stop stepping, or whether to enable the
7536f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata	 * brakpoint, sink remaining signals, and continue
7636f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata	 * everyone.  */
7736f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata	enum callback_status (*keep_stepping_p)
7836f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata		(struct process_stopping_handler *);
7936f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata
80cb9a28da448439eab4bf554810fd1004fbc00885Petr Machata	/* Whether we need to use ugly workaround to get around
81cb9a28da448439eab4bf554810fd1004fbc00885Petr Machata	 * various problems with singlestepping.  */
82cb9a28da448439eab4bf554810fd1004fbc00885Petr Machata	enum callback_status (*ugly_workaround_p)
83cb9a28da448439eab4bf554810fd1004fbc00885Petr Machata		(struct process_stopping_handler *);
84cb9a28da448439eab4bf554810fd1004fbc00885Petr Machata
859282254e29896366ea354b930b06f9defebbd041Petr Machata	enum {
869282254e29896366ea354b930b06f9defebbd041Petr Machata		/* We are waiting for everyone to land in t/T.  */
879282254e29896366ea354b930b06f9defebbd041Petr Machata		psh_stopping = 0,
889282254e29896366ea354b930b06f9defebbd041Petr Machata
899282254e29896366ea354b930b06f9defebbd041Petr Machata		/* We are doing the PTRACE_SINGLESTEP.  */
909282254e29896366ea354b930b06f9defebbd041Petr Machata		psh_singlestep,
919282254e29896366ea354b930b06f9defebbd041Petr Machata
929282254e29896366ea354b930b06f9defebbd041Petr Machata		/* We are waiting for all the SIGSTOPs to arrive so
939282254e29896366ea354b930b06f9defebbd041Petr Machata		 * that we can sink them.  */
949282254e29896366ea354b930b06f9defebbd041Petr Machata		psh_sinking,
959282254e29896366ea354b930b06f9defebbd041Petr Machata
969282254e29896366ea354b930b06f9defebbd041Petr Machata		/* This is for tracking the ugly workaround.  */
979282254e29896366ea354b930b06f9defebbd041Petr Machata		psh_ugly_workaround,
989282254e29896366ea354b930b06f9defebbd041Petr Machata	} state;
999282254e29896366ea354b930b06f9defebbd041Petr Machata
1009282254e29896366ea354b930b06f9defebbd041Petr Machata	int exiting;
1019282254e29896366ea354b930b06f9defebbd041Petr Machata
1029282254e29896366ea354b930b06f9defebbd041Petr Machata	struct pid_set pids;
1039282254e29896366ea354b930b06f9defebbd041Petr Machata};
1049282254e29896366ea354b930b06f9defebbd041Petr Machata
1059282254e29896366ea354b930b06f9defebbd041Petr Machata/* Allocate a process stopping handler, initialize it and install it.
10636f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata * Return 0 on success or a negative value on failure.  Pass NULL for
10736f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata * each callback to use a default instead.  The default for
1081e2a4dd274ebb612e0cfa5c83ef081e5846aa949Petr Machata * ON_ALL_STOPPED is LINUX_PTRACE_DISABLE_AND_SINGLESTEP, the default
1091e2a4dd274ebb612e0cfa5c83ef081e5846aa949Petr Machata * for KEEP_STEPPING_P and UGLY_WORKAROUND_P is "no".  */
1109282254e29896366ea354b930b06f9defebbd041Petr Machataint process_install_stopping_handler
111929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata	(struct process *proc, struct breakpoint *sbp,
11236f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata	 void (*on_all_stopped)(struct process_stopping_handler *),
11336f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata	 enum callback_status (*keep_stepping_p)
114cb9a28da448439eab4bf554810fd1004fbc00885Petr Machata		 (struct process_stopping_handler *),
115cb9a28da448439eab4bf554810fd1004fbc00885Petr Machata	 enum callback_status (*ugly_workaround_p)
11636f40e7d46838ec41ea03a2b9b748536d8fd57e2Petr Machata		(struct process_stopping_handler *));
1179282254e29896366ea354b930b06f9defebbd041Petr Machata
1181e2a4dd274ebb612e0cfa5c83ef081e5846aa949Petr Machatavoid linux_ptrace_disable_and_singlestep(struct process_stopping_handler *self);
1191e2a4dd274ebb612e0cfa5c83ef081e5846aa949Petr Machatavoid linux_ptrace_disable_and_continue(struct process_stopping_handler *self);
1201e2a4dd274ebb612e0cfa5c83ef081e5846aa949Petr Machata
1219282254e29896366ea354b930b06f9defebbd041Petr Machata#endif /* _LTRACE_LINUX_TRACE_H_ */
122