blob: 040a2353ffb72809d8151980b373e17d174af8d8 [file] [log] [blame]
Petr Machata92822542012-03-28 00:31:14 +02001/*
2 * This file is part of ltrace.
3 * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 */
20
21#ifndef _LTRACE_LINUX_TRACE_H_
22#define _LTRACE_LINUX_TRACE_H_
23
24/* This publishes some Linux-specific data structures used for process
25 * handling. */
26
27/**
28 * This is used for bookkeeping related to PIDs that the event
29 * handlers work with.
30 */
31struct pid_task {
32 pid_t pid; /* This may be 0 for tasks that exited
33 * mid-handling. */
34 int sigstopped : 1;
35 int got_event : 1;
36 int delivered : 1;
37 int vforked : 1;
38 int sysret : 1;
39};
40
41struct pid_set {
42 struct pid_task *tasks;
43 size_t count;
44 size_t alloc;
45};
46
47/**
48 * Breakpoint re-enablement. When we hit a breakpoint, we must
49 * disable it, single-step, and re-enable it. That single-step can be
50 * done only by one task in a task group, while others are stopped,
51 * otherwise the processes would race for who sees the breakpoint
52 * disabled and who doesn't. The following is to keep track of it
53 * all.
54 */
55struct process_stopping_handler
56{
57 struct event_handler super;
58
59 /* The task that is doing the re-enablement. */
60 Process *task_enabling_breakpoint;
61
62 /* The pointer being re-enabled. */
63 struct breakpoint *breakpoint_being_enabled;
64
65 /* Artificial atomic skip breakpoint, if any needed. */
66 void *atomic_skip_bp_addr;
67
68 /* When all tasks are stopped, this callback gets called. */
69 void (*on_all_stopped)(struct process_stopping_handler *);
70
71 enum {
72 /* We are waiting for everyone to land in t/T. */
73 psh_stopping = 0,
74
75 /* We are doing the PTRACE_SINGLESTEP. */
76 psh_singlestep,
77
78 /* We are waiting for all the SIGSTOPs to arrive so
79 * that we can sink them. */
80 psh_sinking,
81
82 /* This is for tracking the ugly workaround. */
83 psh_ugly_workaround,
84 } state;
85
86 int exiting;
87
88 struct pid_set pids;
89};
90
91/* Allocate a process stopping handler, initialize it and install it.
92 * Return 0 on success or a negative value on failure. */
93int process_install_stopping_handler
94 (struct Process *proc, struct breakpoint *sbp,
95 void (*cb)(struct process_stopping_handler *));
96
97#endif /* _LTRACE_LINUX_TRACE_H_ */