breakpoints.c revision e50355295eac26e15db259fbb7ff705487b501d0
1e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata/* 2e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This file is part of ltrace. 398ff309cdc98857eb30992f108439cb7d7673598Petr Machata * Copyright (C) 2006,2007,2011,2012,2013 Petr Machata, Red Hat Inc. 4e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2009 Juan Cespedes 5e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 1998,2001,2002,2003,2007,2008,2009 Juan Cespedes 6e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2006 Ian Wienand 7e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 8e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is free software; you can redistribute it and/or 9e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * modify it under the terms of the GNU General Public License as 10e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * published by the Free Software Foundation; either version 2 of the 11e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * License, or (at your option) any later version. 12e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 13e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is distributed in the hope that it will be useful, but 14e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of 15e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * General Public License for more details. 17e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 18e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * You should have received a copy of the GNU General Public License 19e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * along with this program; if not, write to the Free Software 20e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 02110-1301 USA 22e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata */ 23e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata 24d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#include "config.h" 25d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes 265b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes#include <assert.h> 272b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#include <errno.h> 28ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include <stdio.h> 29ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include <stdlib.h> 30ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include <string.h> 315b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 32f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#ifdef __powerpc__ 33f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#include <sys/ptrace.h> 34f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#endif 35f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes 36ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "backend.h" 379294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata#include "breakpoint.h" 38ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "debug.h" 392b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#include "library.h" 40ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "ltrace-elf.h" 41ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "proc.h" 425b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 43c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata#ifndef ARCH_HAVE_TRANSLATE_ADDRESS 44c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machataint 45929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_translate_address_dyn(struct process *proc, 46bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata arch_addr_t addr, arch_addr_t *ret) 47b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata{ 48b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata *ret = addr; 49b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata return 0; 50b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata} 51b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata 52b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machatastruct ltelf; 53b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machataint 54b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machataarch_translate_address(struct ltelf *lte, 55bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata arch_addr_t addr, arch_addr_t *ret) 56c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata{ 57c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata *ret = addr; 58c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata return 0; 59c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata} 60c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata#endif 61c67a6e62bc7e95f7f181a51c5b314ef10a6e231ePetr Machata 62a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machatavoid 63929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_on_hit(struct breakpoint *bp, struct process *proc) 64a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata{ 65a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata assert(bp != NULL); 66a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata if (bp->cbs != NULL && bp->cbs->on_hit != NULL) 6755ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata (bp->cbs->on_hit)(bp, proc); 6855ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata} 6955ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata 7055ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatavoid 71929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_on_continue(struct breakpoint *bp, struct process *proc) 7255ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata{ 7355ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata assert(bp != NULL); 7455ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata if (bp->cbs != NULL && bp->cbs->on_continue != NULL) 7555ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata (bp->cbs->on_continue)(bp, proc); 7655ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata else 7755ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata continue_after_breakpoint(proc, bp); 78a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata} 79a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata 8086d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machatavoid 81929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_on_retract(struct breakpoint *bp, struct process *proc) 8286d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata{ 8386d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata assert(bp != NULL); 8486d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata if (bp->cbs != NULL && bp->cbs->on_retract != NULL) 8586d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata (bp->cbs->on_retract)(bp, proc); 8686d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata} 8786d3828129e70222abdb77bdda6f31a7f1eafd5aPetr Machata 885b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes/*****************************************************************************/ 895b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 909294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machatastruct breakpoint * 91d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machataaddress2bpstruct(struct process *proc, arch_addr_t addr) 92fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 932662768efe599f6bb43c4310177e30f56b601bb7Petr Machata assert(proc != NULL); 942662768efe599f6bb43c4310177e30f56b601bb7Petr Machata assert(proc->breakpoints != NULL); 959a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(proc->leader == proc); 96cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr); 97d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata 9898ff309cdc98857eb30992f108439cb7d7673598Petr Machata struct breakpoint *found; 9998ff309cdc98857eb30992f108439cb7d7673598Petr Machata if (DICT_FIND_VAL(proc->breakpoints, &addr, &found) < 0) 100d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata return NULL; 10198ff309cdc98857eb30992f108439cb7d7673598Petr Machata return found; 1025b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 1035b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 1048cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata#ifndef ARCH_HAVE_BREAKPOINT_DATA 1052b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataint 106929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_breakpoint_init(struct process *proc, struct breakpoint *sbp) 1072b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{ 1082b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata return 0; 1092b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata} 1108cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata 1118cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatavoid 1128cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machataarch_breakpoint_destroy(struct breakpoint *sbp) 1138cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata{ 1148cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata} 115d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata 116d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataint 117d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataarch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) 118d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{ 119d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata return 0; 120d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata} 1212b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#endif 1222b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata 123d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machatastatic void 124e50355295eac26e15db259fbb7ff705487b501d0Petr Machatabreakpoint_init_base(struct breakpoint *bp, 125bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata arch_addr_t addr, struct library_symbol *libsym) 126d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{ 127d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata bp->cbs = NULL; 128d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata bp->addr = addr; 129d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata memset(bp->orig_value, 0, sizeof(bp->orig_value)); 130d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata bp->enabled = 0; 131d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata bp->libsym = libsym; 132d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata} 133d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata 13452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata/* On second thought, I don't think we need PROC. All the translation 13552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * (arch_translate_address in particular) should be doable using 13652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * static lookups of various sections in the ELF file. We shouldn't 13752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * need process for anything. */ 1382b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataint 139929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_init(struct breakpoint *bp, struct process *proc, 140bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata arch_addr_t addr, struct library_symbol *libsym) 1412b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{ 142e50355295eac26e15db259fbb7ff705487b501d0Petr Machata breakpoint_init_base(bp, addr, libsym); 1432b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata return arch_breakpoint_init(proc, bp); 1442b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata} 1452b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata 1468cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatavoid 14755ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatabreakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs) 14855ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata{ 14955ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata if (bp->cbs != NULL) 15055ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata assert(bp->cbs == NULL); 15155ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata bp->cbs = cbs; 15255ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata} 15355ac932f2802f85c53792153ac909dcd8a690c5cPetr Machata 15455ac932f2802f85c53792153ac909dcd8a690c5cPetr Machatavoid 1558cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machatabreakpoint_destroy(struct breakpoint *bp) 1568cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata{ 1578cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata if (bp == NULL) 1588cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata return; 159d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata arch_breakpoint_destroy(bp); 160d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata} 1618cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata 162d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machataint 163929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_clone(struct breakpoint *retp, struct process *new_proc, 164e50355295eac26e15db259fbb7ff705487b501d0Petr Machata struct breakpoint *bp) 165d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata{ 166165b566a50b2bd560af3bd9649e456915397066bPetr Machata struct library_symbol *libsym = NULL; 167165b566a50b2bd560af3bd9649e456915397066bPetr Machata if (bp->libsym != NULL) { 168165b566a50b2bd560af3bd9649e456915397066bPetr Machata int rc = proc_find_symbol(new_proc, bp->libsym, NULL, &libsym); 169165b566a50b2bd560af3bd9649e456915397066bPetr Machata assert(rc == 0); 170d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata } 171d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata 172e50355295eac26e15db259fbb7ff705487b501d0Petr Machata breakpoint_init_base(retp, bp->addr, libsym); 173d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata memcpy(retp->orig_value, bp->orig_value, sizeof(bp->orig_value)); 174d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata retp->enabled = bp->enabled; 175d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata if (arch_breakpoint_clone(retp, bp) < 0) 176d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata return -1; 177d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata breakpoint_set_callbacks(retp, bp->cbs); 178d3cc9889fdfe2e523e99ca5f664f8ae4b3936612Petr Machata return 0; 1798cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata} 1808cce1193ebd35cb5a8b288bc7325cdda1b8ffe50Petr Machata 18152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint 182929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_turn_on(struct breakpoint *bp, struct process *proc) 18352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{ 18452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata bp->enabled++; 18552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata if (bp->enabled == 1) { 186fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata assert(proc->pid != 0); 187fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata enable_breakpoint(proc, bp); 18852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata } 18952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return 0; 19052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata} 19152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 19252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint 193929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoint_turn_off(struct breakpoint *bp, struct process *proc) 19452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{ 19552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata bp->enabled--; 19652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata if (bp->enabled == 0) 197fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata disable_breakpoint(proc, bp); 19852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata assert(bp->enabled >= 0); 19952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return 0; 20052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata} 20152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 2029294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machatastruct breakpoint * 203d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatainsert_breakpoint(struct process *proc, arch_addr_t addr, 2049df15016447915a61526af8cb81c588913bcf44cPetr Machata struct library_symbol *libsym) 205fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 206929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata struct process *leader = proc->leader; 2079a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 2089a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata /* Only the group leader should be getting the breakpoints and 2099a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata * thus have ->breakpoint initialized. */ 2109a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(leader != NULL); 2119a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(leader->breakpoints != NULL); 2129a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 213050b0a6fd01fc01952c0ab8dbb84d6eba65c71c9Petr Machata debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)", 214050b0a6fd01fc01952c0ab8dbb84d6eba65c71c9Petr Machata proc->pid, addr, libsym ? libsym->name : "NULL"); 2155b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 216218c5ff26841f5bbd188c42ccbd67422a7a20556Petr Machata assert(addr != 0); 2179a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand 21852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata /* XXX what we need to do instead is have a list of 21952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * breakpoints that are enabled at this address. The 22052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * following works if every breakpoint is the same and there's 22152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * no extra data, but that doesn't hold anymore. For now it 22252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * will suffice, about the only realistic case where we need 22352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * to have more than one breakpoint per address is return from 22452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata * a recursive library call. */ 225d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata struct breakpoint *bp; 22698ff309cdc98857eb30992f108439cb7d7673598Petr Machata if (DICT_FIND_VAL(leader->breakpoints, &addr, &bp) < 0) { 227d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata bp = malloc(sizeof(*bp)); 228d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata if (bp == NULL 229d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata || breakpoint_init(bp, proc, addr, libsym) < 0) { 230d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata free(bp); 23152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return NULL; 23252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata } 233d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata if (proc_add_breakpoint(leader, bp) < 0) { 23452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata fail: 235d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata breakpoint_destroy(bp); 236d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata free(bp); 2372b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata return NULL; 238cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes } 2395b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes } 2402b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata 241d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata if (breakpoint_turn_on(bp, proc) < 0) { 242d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata proc_remove_breakpoint(leader, bp); 24352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata goto fail; 2444572877d0dd0b5060f4498e705467eaef51c6459Petr Machata } 2459294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata 246d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata return bp; 2475b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 2485b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 249f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 250d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatadelete_breakpoint(struct process *proc, arch_addr_t addr) 251fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 252cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr); 253cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 254929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata struct process *leader = proc->leader; 2559a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(leader != NULL); 2569a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 25798ff309cdc98857eb30992f108439cb7d7673598Petr Machata struct breakpoint *sbp = NULL; 25898ff309cdc98857eb30992f108439cb7d7673598Petr Machata DICT_FIND_VAL(leader->breakpoints, &addr, &sbp); 259f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata assert(sbp != NULL); 2605b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 261fa0c5704352beb3f81efe8970dbd5af45a4b00cePetr Machata if (breakpoint_turn_off(sbp, proc) < 0) { 26252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n", 26352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata breakpoint_name(sbp), sbp->addr); 26452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return; 26552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata } 266f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata if (sbp->enabled == 0) { 267f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata proc_remove_breakpoint(leader, sbp); 268f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata breakpoint_destroy(sbp); 269f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata free(sbp); 270f7fee43f72667f453bba5aaeea6b5490ece6792aPetr Machata } 2715b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 2725b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 273e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machataconst char * 274e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machatabreakpoint_name(const struct breakpoint *bp) 275e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata{ 276e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata assert(bp != NULL); 277e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata return bp->libsym != NULL ? bp->libsym->name : NULL; 278e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata} 279e9aebd6cfb4710f96b27b5d268208ddd7f0d9eacPetr Machata 28052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatastruct library * 28152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatabreakpoint_library(const struct breakpoint *bp) 28252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{ 28352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata assert(bp != NULL); 28452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return bp->libsym != NULL ? bp->libsym->lib : NULL; 28552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata} 28652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 287d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatastatic enum callback_status 288d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machataenable_bp_cb(arch_addr_t *addr, struct breakpoint **bpp, void *data) 289fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 290d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata struct process *proc = data; 291d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", proc->pid); 292d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata if ((*bpp)->enabled) 293d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata enable_breakpoint(proc, *bpp); 294d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata return CBS_CONT; 2955b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 2965b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 297f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 298929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataenable_all_breakpoints(struct process *proc) 299bc37326ace5c70e57928c000162cffbcca9afb77Petr Machata{ 300cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid); 301f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes 30261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata debug(1, "Enabling breakpoints for pid %u...", proc->pid); 303d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata if (proc->breakpoints != NULL) 304d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata DICT_EACH(proc->breakpoints, arch_addr_t, struct breakpoint *, 305d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata NULL, enable_bp_cb, proc); 3065e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes} 3075e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 308d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatastatic enum callback_status 309d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machatadisable_bp_cb(arch_addr_t *addr, struct breakpoint **bpp, void *data) 310fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 311d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata struct process *proc = data; 312d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", proc->pid); 313d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata if ((*bpp)->enabled) 314d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata disable_breakpoint(proc, *bpp); 315d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata return CBS_CONT; 3165b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 3175b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 318f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 319929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatadisable_all_breakpoints(struct process *proc) 320929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata{ 321cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid); 3229a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(proc->leader == proc); 323d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata DICT_EACH(proc->breakpoints, arch_addr_t, struct breakpoint *, 324d7e4ca82e1cf20bb2605befb1da74dd1688c706ePetr Machata NULL, disable_bp_cb, proc); 3255e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes} 3267186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 327d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata/* XXX This is not currently properly supported. On clone, this is 328d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * just sliced. Hopefully at the point that clone is done, this 329d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * breakpoint is not necessary anymore. If this use case ends up 330d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * being important, we need to add a clone and destroy callbacks to 331d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * breakpoints, and we should also probably drop arch_breakpoint_data 332d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * so that we don't end up with two different customization mechanisms 333d09d240bbb62af2b0a15e6bdba4114b4060d11caPetr Machata * for one structure. */ 33452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatastruct entry_breakpoint { 33552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata struct breakpoint super; 336bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata arch_addr_t dyn_addr; 33752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata}; 33852dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 33902648a119092bb5b64918063521237f257283c72Petr Machatastatic void 340929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataentry_breakpoint_on_hit(struct breakpoint *a, struct process *proc) 34102648a119092bb5b64918063521237f257283c72Petr Machata{ 34252dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata struct entry_breakpoint *bp = (void *)a; 34302648a119092bb5b64918063521237f257283c72Petr Machata if (proc == NULL || proc->leader == NULL) 34402648a119092bb5b64918063521237f257283c72Petr Machata return; 345bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata arch_addr_t dyn_addr = bp->dyn_addr; 3463fd099b71ae9e0c4fe9f48a239523e7037e4baf4Petr Machata delete_breakpoint(proc, bp->super.addr); 3475ee368270823922ee2a11f0637a355641f6af457Petr Machata linkmap_init(proc, dyn_addr); 34893d95dff48698b8bde511c7f71acda7646da2626Petr Machata arch_dynlink_done(proc); 34952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata} 35052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 35152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machataint 352929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataentry_breakpoint_init(struct process *proc, 353bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata struct entry_breakpoint *bp, arch_addr_t addr, 3549a04d0ef18b9d019b87ba10adee27f41980b286fPetr Machata struct library *lib) 35552dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata{ 3561c79025768a4403e016cc59d7f41b266e868c9e6Petr Machata assert(addr != 0); 3571c79025768a4403e016cc59d7f41b266e868c9e6Petr Machata int err = breakpoint_init(&bp->super, proc, addr, NULL); 3581c79025768a4403e016cc59d7f41b266e868c9e6Petr Machata if (err < 0) 35952dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return err; 36052dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 36152dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata static struct bp_callbacks entry_callbacks = { 36212affff3c88731a0880690442485494e540f7a58Petr Machata .on_hit = entry_breakpoint_on_hit, 36352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata }; 36452dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata bp->super.cbs = &entry_callbacks; 3659a04d0ef18b9d019b87ba10adee27f41980b286fPetr Machata bp->dyn_addr = lib->dyn_addr; 36652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata return 0; 36702648a119092bb5b64918063521237f257283c72Petr Machata} 36802648a119092bb5b64918063521237f257283c72Petr Machata 3691974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machataint 370929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatabreakpoints_init(struct process *proc) 371c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata{ 372cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid); 3732662768efe599f6bb43c4310177e30f56b601bb7Petr Machata 3742b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata /* XXX breakpoint dictionary should be initialized 3752b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata * outside. Here we just put in breakpoints. */ 3762b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata assert(proc->breakpoints != NULL); 3777186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 3782b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata /* Only the thread group leader should hold the breakpoints. */ 3792b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata assert(proc->leader == proc); 3803d7e4b8d6119c1cda159e2665b40b6dcd4052e85Petr Machata 381807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata /* N.B. the following used to be conditional on this, and 382807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata * maybe it still needs to be. */ 383807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata assert(proc->filename != NULL); 384807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata 385807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata struct library *lib = ltelf_read_main_binary(proc, proc->filename); 386807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata struct entry_breakpoint *entry_bp = NULL; 387807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata int bp_state = 0; 388807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata int result = -1; 3896bb420106f77ef8f134a1d4c001668e832f96cc9Andrey Zonov switch ((int)(lib != NULL)) { 390807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata fail: 391807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata switch (bp_state) { 392807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata case 2: 393a24163658be2cc9249621701e6d056df0063f52fPetr Machata proc_remove_library(proc, lib); 394807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata proc_remove_breakpoint(proc, &entry_bp->super); 395807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata case 1: 396807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata breakpoint_destroy(&entry_bp->super); 3971974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata } 398a24163658be2cc9249621701e6d056df0063f52fPetr Machata library_destroy(lib); 399807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata free(entry_bp); 400807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata case 0: 401807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata return result; 402807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata } 40352dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machata 404807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata entry_bp = malloc(sizeof(*entry_bp)); 405807cdd874087db852e3b67f2b9100d3eb1cab366Petr Machata if (entry_bp == NULL 40691c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata || (entry_breakpoint_init(proc, entry_bp, 40791c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata lib->entry, lib)) < 0) { 40891c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata fprintf(stderr, 40991c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata "Couldn't initialize entry breakpoint for PID %d.\n" 41091c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata "Some tracing events may be missed.\n", proc->pid); 41191c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata free(entry_bp); 4120092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata 41391c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata } else { 41491c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata ++bp_state; 4150092820afcd45fe045ccc294b061bce8da00a1f2Petr Machata 41691c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata if ((result = proc_add_breakpoint(proc, &entry_bp->super)) < 0) 41791c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata goto fail; 41891c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata ++bp_state; 41991c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata 42091c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata if ((result = breakpoint_turn_on(&entry_bp->super, proc)) < 0) 42191c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata goto fail; 42291c399c086b3a1895a299dee4c6181b56b6437ddPetr Machata } 423a24163658be2cc9249621701e6d056df0063f52fPetr Machata proc_add_library(proc, lib); 424a24163658be2cc9249621701e6d056df0063f52fPetr Machata 4257186e2af704f4458e6383e8a92482594db29b597Juan Cespedes proc->callstack_depth = 0; 4261974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata return 0; 4277186e2af704f4458e6383e8a92482594db29b597Juan Cespedes} 428