trace.h revision 96cb8e3111924780ed1d757e865a83f26421e616
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. */ 8796cb8e3111924780ed1d757e865a83f26421e616Petr Machata PSH_STOPPING = 0, 889282254e29896366ea354b930b06f9defebbd041Petr Machata 899282254e29896366ea354b930b06f9defebbd041Petr Machata /* We are doing the PTRACE_SINGLESTEP. */ 9096cb8e3111924780ed1d757e865a83f26421e616Petr Machata PSH_SINGLESTEP, 919282254e29896366ea354b930b06f9defebbd041Petr Machata 929282254e29896366ea354b930b06f9defebbd041Petr Machata /* We are waiting for all the SIGSTOPs to arrive so 939282254e29896366ea354b930b06f9defebbd041Petr Machata * that we can sink them. */ 9496cb8e3111924780ed1d757e865a83f26421e616Petr Machata PSH_SINKING, 959282254e29896366ea354b930b06f9defebbd041Petr Machata 969282254e29896366ea354b930b06f9defebbd041Petr Machata /* This is for tracking the ugly workaround. */ 9796cb8e3111924780ed1d757e865a83f26421e616Petr 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