| OLD | NEW |
| 1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
| 5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
| 6 // | 6 // |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 // | 8 // |
| 9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 mach_msg_header_t* Header() const { | 36 mach_msg_header_t* Header() const { |
| 37 return reinterpret_cast<mach_msg_header_t*>(vm_.address()); | 37 return reinterpret_cast<mach_msg_header_t*>(vm_.address()); |
| 38 } | 38 } |
| 39 | 39 |
| 40 //! \brief Ensures that this object has a buffer of exactly \a size bytes | 40 //! \brief Ensures that this object has a buffer of exactly \a size bytes |
| 41 //! available. | 41 //! available. |
| 42 //! | 42 //! |
| 43 //! If the existing buffer is a different size, it will be reallocated without | 43 //! If the existing buffer is a different size, it will be reallocated without |
| 44 //! copying any of the old buffer’s contents to the new buffer. The contents | 44 //! copying any of the old buffer’s contents to the new buffer. The contents |
| 45 //! of the buffer are unspecified after this call, even if no reallocation is | 45 //! of the buffer are unspecified after this call, even if no reallocation is |
| 46 //! made. | 46 //! performed. |
| 47 kern_return_t Reallocate(vm_size_t size) { | 47 kern_return_t Reallocate(vm_size_t size) { |
| 48 // This test uses == instead of > so that a large reallocation to receive a | 48 // This test uses == instead of > so that a large reallocation to receive a |
| 49 // large message doesn’t cause permanent memory bloat for the duration of | 49 // large message doesn’t cause permanent memory bloat for the duration of |
| 50 // a MachMessageServer::Run() loop. | 50 // a MachMessageServer::Run() loop. |
| 51 if (size == vm_.size()) { | 51 if (size == vm_.size()) { |
| 52 return KERN_SUCCESS; | 52 return KERN_SUCCESS; |
| 53 } | 53 } |
| 54 | 54 |
| 55 // reset() first, so that two allocations don’t exist simultaneously. | 55 // reset() first, so that two allocations don’t exist simultaneously. |
| 56 vm_.reset(); | 56 vm_.reset(); |
| 57 | 57 |
| 58 vm_address_t address; | 58 if (size) { |
| 59 kern_return_t kr = | 59 vm_address_t address; |
| 60 vm_allocate(mach_task_self(), | 60 kern_return_t kr = |
| 61 &address, | 61 vm_allocate(mach_task_self(), |
| 62 size, | 62 &address, |
| 63 VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_MACH_MSG)); | 63 size, |
| 64 if (kr != KERN_SUCCESS) { | 64 VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_MACH_MSG)); |
| 65 return kr; | 65 if (kr != KERN_SUCCESS) { |
| 66 return kr; |
| 67 } |
| 68 |
| 69 vm_.reset(address, size); |
| 66 } | 70 } |
| 67 | 71 |
| 68 vm_.reset(address, size); | |
| 69 return KERN_SUCCESS; | 72 return KERN_SUCCESS; |
| 70 } | 73 } |
| 71 | 74 |
| 72 private: | 75 private: |
| 73 base::mac::ScopedMachVM vm_; | 76 base::mac::ScopedMachVM vm_; |
| 74 | 77 |
| 75 DISALLOW_COPY_AND_ASSIGN(MachMessageBuffer); | 78 DISALLOW_COPY_AND_ASSIGN(MachMessageBuffer); |
| 76 }; | 79 }; |
| 77 | 80 |
| 78 // Wraps MachMessageWithDeadline(), using a MachMessageBuffer argument which | 81 // Wraps MachMessageWithDeadline(), using a MachMessageBuffer argument which |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 } else { | 137 } else { |
| 135 options &= ~MACH_RCV_LARGE; | 138 options &= ~MACH_RCV_LARGE; |
| 136 } | 139 } |
| 137 | 140 |
| 138 const mach_msg_size_t trailer_alloc = REQUESTED_TRAILER_SIZE(options); | 141 const mach_msg_size_t trailer_alloc = REQUESTED_TRAILER_SIZE(options); |
| 139 const mach_msg_size_t expected_receive_size = | 142 const mach_msg_size_t expected_receive_size = |
| 140 round_msg(interface->MachMessageServerRequestSize()) + trailer_alloc; | 143 round_msg(interface->MachMessageServerRequestSize()) + trailer_alloc; |
| 141 const mach_msg_size_t request_size = (receive_large == kReceiveLargeResize) | 144 const mach_msg_size_t request_size = (receive_large == kReceiveLargeResize) |
| 142 ? round_page(expected_receive_size) | 145 ? round_page(expected_receive_size) |
| 143 : expected_receive_size; | 146 : expected_receive_size; |
| 147 DCHECK_GE(request_size, sizeof(mach_msg_empty_rcv_t)); |
| 144 | 148 |
| 145 // mach_msg_server() and mach_msg_server_once() would consider whether | 149 // mach_msg_server() and mach_msg_server_once() would consider whether |
| 146 // |options| contains MACH_SEND_TRAILER and include MAX_TRAILER_SIZE in this | 150 // |options| contains MACH_SEND_TRAILER and include MAX_TRAILER_SIZE in this |
| 147 // computation if it does, but that option is ineffective on OS X. | 151 // computation if it does, but that option is ineffective on OS X. |
| 148 const mach_msg_size_t reply_alloc = | 152 const mach_msg_size_t reply_size = interface->MachMessageServerReplySize(); |
| 149 round_page(interface->MachMessageServerReplySize()); | 153 DCHECK_GE(reply_size, sizeof(mach_msg_empty_send_t)); |
| 154 const mach_msg_size_t reply_alloc = round_page(reply_size); |
| 150 | 155 |
| 151 MachMessageBuffer request; | 156 MachMessageBuffer request; |
| 152 MachMessageBuffer reply; | 157 MachMessageBuffer reply; |
| 153 bool received_any_request = false; | 158 bool received_any_request = false; |
| 154 bool retry; | 159 bool retry; |
| 155 | 160 |
| 156 kern_return_t kr; | 161 kern_return_t kr; |
| 157 | 162 |
| 158 do { | 163 do { |
| 159 retry = false; | 164 retry = false; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 177 // alternatives, which might involve returning MACH_MSG_SUCCESS, | 182 // alternatives, which might involve returning MACH_MSG_SUCCESS, |
| 178 // MACH_RCV_TIMED_OUT, or MACH_RCV_TOO_LARGE to a caller that | 183 // MACH_RCV_TIMED_OUT, or MACH_RCV_TOO_LARGE to a caller that |
| 179 // specified one-shot behavior, all seem less correct than retrying. | 184 // specified one-shot behavior, all seem less correct than retrying. |
| 180 MACH_LOG(WARNING, kr) << "mach_msg: ignoring large message"; | 185 MACH_LOG(WARNING, kr) << "mach_msg: ignoring large message"; |
| 181 retry = true; | 186 retry = true; |
| 182 continue; | 187 continue; |
| 183 | 188 |
| 184 case kReceiveLargeResize: { | 189 case kReceiveLargeResize: { |
| 185 mach_msg_size_t this_request_size = round_page( | 190 mach_msg_size_t this_request_size = round_page( |
| 186 round_msg(request.Header()->msgh_size) + trailer_alloc); | 191 round_msg(request.Header()->msgh_size) + trailer_alloc); |
| 192 DCHECK_GT(this_request_size, request_size); |
| 187 | 193 |
| 188 kr = MachMessageAllocateReceive(&request, | 194 kr = MachMessageAllocateReceive(&request, |
| 189 options & ~MACH_RCV_LARGE, | 195 options & ~MACH_RCV_LARGE, |
| 190 this_request_size, | 196 this_request_size, |
| 191 receive_port, | 197 receive_port, |
| 192 deadline, | 198 deadline, |
| 193 MACH_PORT_NULL, | 199 MACH_PORT_NULL, |
| 194 !received_any_request); | 200 !received_any_request); |
| 195 | 201 |
| 196 break; | 202 break; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 } | 271 } |
| 266 return kr; | 272 return kr; |
| 267 } | 273 } |
| 268 } | 274 } |
| 269 } while (persistent == kPersistent || retry); | 275 } while (persistent == kPersistent || retry); |
| 270 | 276 |
| 271 return kr; | 277 return kr; |
| 272 } | 278 } |
| 273 | 279 |
| 274 } // namespace crashpad | 280 } // namespace crashpad |
| OLD | NEW |