1 /* Copyright (C) 2017 The Android Open Source Project 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This file implements interfaces from the file jdwpTransport.h. This implementation 5 * is licensed under the same terms as the file jdwpTransport.h. The 6 * copyright and license information for the file jdwpTranport.h follows. 7 * 8 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10 * 11 * This code is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License version 2 only, as 13 * published by the Free Software Foundation. Oracle designates this 14 * particular file as subject to the "Classpath" exception as provided 15 * by Oracle in the LICENSE file that accompanied this code. 16 * 17 * This code is distributed in the hope that it will be useful, but WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 * version 2 for more details (a copy is included in the LICENSE file that 21 * accompanied this code). 22 * 23 * You should have received a copy of the GNU General Public License version 24 * 2 along with this work; if not, write to the Free Software Foundation, 25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26 * 27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28 * or visit www.oracle.com if you need additional information or have any 29 * questions. 30 */ 31 32 #ifndef ART_DT_FD_FORWARD_DT_FD_FORWARD_H_ 33 #define ART_DT_FD_FORWARD_DT_FD_FORWARD_H_ 34 35 #include <atomic> 36 #include <condition_variable> 37 #include <mutex> 38 #include <string> 39 40 #include <android-base/logging.h> 41 #include <android-base/thread_annotations.h> 42 #include <android-base/unique_fd.h> 43 44 #include <arpa/inet.h> 45 #include <sys/eventfd.h> 46 #include <unistd.h> 47 #include <poll.h> 48 49 #include <jni.h> 50 #include <jvmti.h> 51 #include <jdwpTransport.h> 52 53 #include "fd_transport.h" 54 55 namespace dt_fd_forward { 56 57 static constexpr uint8_t kReplyFlag = 0x80; 58 // Macro and constexpr to make error values less annoying to write. 59 #define ERR(e) JDWPTRANSPORT_ERROR_ ## e 60 static constexpr jdwpTransportError OK = ERR(NONE); 61 62 static constexpr const char kJdwpHandshake[14] = { 63 'J', 'D', 'W', 'P', '-', 'H', 'a', 'n', 'd', 's', 'h', 'a', 'k', 'e' 64 }; // "JDWP-Handshake" 65 66 enum class TransportState { 67 kClosed, // Main state. 68 kListenSetup, // Transient, wait for the state to change before proceeding. 69 kListening, // Main state. 70 kOpening, // Transient, wait for the state to change before proceeding. 71 kOpen, // Main state. 72 }; 73 74 enum class IOResult { 75 kOk, kInterrupt, kError, kEOF, 76 }; 77 78 class PacketReader; 79 class PacketWriter; 80 81 // TODO It would be good to get the thread-safety analysis checks working but first we would need to 82 // use something other than std::mutex which does not have the annotations required. 83 class FdForwardTransport : public jdwpTransportEnv { 84 public: 85 explicit FdForwardTransport(jdwpTransportCallback* cb); 86 ~FdForwardTransport(); 87 88 jdwpTransportError PerformAttach(int listen_fd); 89 jdwpTransportError SetupListen(int listen_fd); 90 jdwpTransportError StopListening(); 91 92 jboolean IsOpen(); 93 94 jdwpTransportError WritePacket(const jdwpPacket* pkt); 95 jdwpTransportError ReadPacket(jdwpPacket* pkt); 96 jdwpTransportError Close(); 97 jdwpTransportError Accept(); 98 jdwpTransportError GetLastError(/*out*/char** description); 99 100 void* Alloc(size_t data); 101 void Free(void* data); 102 103 private: 104 void SetLastError(const std::string& desc); 105 106 bool ChangeState(TransportState old_state, TransportState new_state); // REQUIRES(state_mutex_); 107 108 // Gets the fds from the server side. do_handshake returns whether the transport can skip the 109 // jdwp handshake. 110 IOResult ReceiveFdsFromSocket(/*out*/bool* do_handshake); 111 112 IOResult WriteFully(const void* data, size_t ndata); // REQUIRES(!state_mutex_); 113 IOResult WriteFullyWithoutChecks(const void* data, size_t ndata); // REQUIRES(state_mutex_); 114 IOResult ReadFully(void* data, size_t ndata); // REQUIRES(!state_mutex_); 115 IOResult ReadUpToMax(void* data, size_t ndata, /*out*/size_t* amount_read); 116 // REQUIRES(state_mutex_); 117 IOResult ReadFullyWithoutChecks(void* data, size_t ndata); // REQUIRES(state_mutex_); 118 119 void CloseFdsLocked(); // REQUIRES(state_mutex_) 120 121 // The allocation/deallocation functions. 122 jdwpTransportCallback mem_; 123 124 // Input from the server; 125 android::base::unique_fd read_fd_; // GUARDED_BY(state_mutex_); 126 // Output to the server; 127 android::base::unique_fd write_fd_; // GUARDED_BY(state_mutex_); 128 129 // an eventfd passed with the write_fd to the transport that we will 'read' from to get a lock on 130 // the write_fd_. The other side must not hold it for unbounded time. 131 android::base::unique_fd write_lock_fd_; // GUARDED_BY(state_mutex_); 132 133 // Eventfd we will use to wake-up paused reads for close(). 134 android::base::unique_fd wakeup_fd_; 135 136 // Socket we will get the read/write fd's from. 137 android::base::unique_fd listen_fd_; 138 139 // Fd we will write close notification to. This is a dup of listen_fd_. 140 android::base::unique_fd close_notify_fd_; 141 142 TransportState state_; // GUARDED_BY(state_mutex_); 143 144 std::mutex state_mutex_; 145 std::condition_variable state_cv_; 146 147 // A counter that we use to make sure we don't do half a read on one and half on another fd. 148 std::atomic<uint64_t> current_seq_num_; 149 150 friend class PacketReader; // For ReadFullyWithInterrupt 151 friend class PacketWriter; // For WriteFullyWithInterrupt 152 }; 153 154 } // namespace dt_fd_forward 155 156 #endif // ART_DT_FD_FORWARD_DT_FD_FORWARD_H_ 157