Bug Summary

File:root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/crashreporter/breakpad-client/linux/./../../../../../toolkit/crashreporter/breakpad-client/linux/crash_generation/crash_generation_server.cc
Warning:line 358, column 5
Value stored to 'res' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_linux0.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/crashreporter/breakpad-client/linux -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/crashreporter/breakpad-client/linux -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D COMMON_LINUX_GUID_CREATOR_H__=1 -D NO_STABS_SUPPORT -D MOZ_PHC -D MOZ_HAS_MOZGLUE -I /root/firefox-clang/toolkit/crashreporter/breakpad-client/linux -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/toolkit/crashreporter/breakpad-client/linux -I /root/firefox-clang/toolkit/crashreporter/breakpad-client -I /root/firefox-clang/toolkit/crashreporter/google-breakpad/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -Wno-unused-local-typedefs -Wno-deprecated-declarations -Wno-bool-compare -Wno-unused-but-set-variable -Wno-c++11-narrowing -Wno-implicit-fallthrough -Wno-error=stack-protector -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-11-12-001017-1011516-1 -x c++ Unified_cpp_linux0.cpp
1// Copyright (c) 2010 Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#include <assert.h>
31#include <dirent.h>
32#include <fcntl.h>
33#include <limits.h>
34#include <poll.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <sys/socket.h>
39#include <sys/stat.h>
40#include <sys/types.h>
41#include <unistd.h>
42
43#include <vector>
44
45#include "linux/crash_generation/crash_generation_server.h"
46#include "linux/crash_generation/crash_generation.h"
47#include "linux/crash_generation/client_info.h"
48#include "linux/handler/exception_handler.h"
49#include "linux/handler/guid_generator.h"
50#include "linux/minidump_writer/minidump_writer.h"
51#include "linux/log/log.h"
52#include "common/linux/eintr_wrapper.h"
53#include "common/linux/safe_readlink.h"
54
55#if defined(MOZ_OXIDIZED_BREAKPAD1)
56# include "mozilla/toolkit/crashreporter/rust_minidump_writer_linux_ffi_generated.h"
57#endif // defined(MOZ_OXIDIZED_BREAKPAD)
58
59static const char kCommandQuit = 'x';
60
61namespace google_breakpad {
62
63using CrashReporter::UniqueFd;
64using CrashReporter::GenerationClientAction;
65
66CrashGenerationServer::CrashGenerationServer(
67 const int listen_fd,
68#if defined(MOZ_OXIDIZED_BREAKPAD1)
69 std::function<GetAuxvInfoCallback> get_auxv_info,
70#endif // defined(MOZ_OXIDIZED_BREAKPAD)
71 std::function<OnClientDumpRequestCallback> dump_callback,
72 void* dump_context,
73 const string* dump_path) :
74 server_fd_(listen_fd),
75#if defined(MOZ_OXIDIZED_BREAKPAD1)
76 get_auxv_info_(std::move(get_auxv_info)),
77 force_remote_executor_(getenv("MOZ_CRASHREPORTER_FORCE_REMOTE_EXECUTOR") != nullptr),
78#endif // defined(MOZ_OXIDIZED_BREAKPAD)
79 dump_callback_(std::move(dump_callback)),
80 dump_context_(dump_context),
81 dump_dir_mutex_(PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, PTHREAD_MUTEX_TIMED_NP, 0, 0, { __null, __null
} } }
),
82 started_(false)
83{
84 if (dump_path)
85 dump_dir_ = *dump_path;
86 else
87 dump_dir_ = "/tmp";
88}
89
90CrashGenerationServer::~CrashGenerationServer()
91{
92 if (started_)
93 Stop();
94}
95
96bool
97CrashGenerationServer::Start()
98{
99 if (started_ || 0 > server_fd_)
100 return false;
101
102 int control_pipe[2];
103 if (pipe(control_pipe))
104 return false;
105
106 if (fcntl(control_pipe[0], F_SETFD2, FD_CLOEXEC1))
107 return false;
108 if (fcntl(control_pipe[1], F_SETFD2, FD_CLOEXEC1))
109 return false;
110
111 if (fcntl(control_pipe[0], F_SETFL4, O_NONBLOCK04000))
112 return false;
113
114 control_pipe_in_ = control_pipe[0];
115 control_pipe_out_ = control_pipe[1];
116
117 if (pthread_create(&thread_, nullptr,
118 [](void* context) -> void* {
119 reinterpret_cast<CrashGenerationServer*>(context)->Run();
120 return nullptr;
121 }, this))
122 return false;
123
124 started_ = true;
125 return true;
126}
127
128void
129CrashGenerationServer::Stop()
130{
131 assert(pthread_self() != thread_)(static_cast <bool> (pthread_self() != thread_) ? void (
0) : __assert_fail ("pthread_self() != thread_", __builtin_FILE
(), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__))
;
132
133 if (!started_)
134 return;
135
136 HANDLE_EINTR(write(control_pipe_out_, &kCommandQuit, 1))({ __typeof__(write(control_pipe_out_, &kCommandQuit, 1))
eintr_wrapper_result; do { eintr_wrapper_result = (write(control_pipe_out_
, &kCommandQuit, 1)); } while (eintr_wrapper_result == -1
&& (*__errno_location ()) == 4); eintr_wrapper_result
; })
;
137
138 void* dummy;
139 pthread_join(thread_, &dummy);
140
141 close(control_pipe_in_);
142 close(control_pipe_out_);
143
144 started_ = false;
145}
146
147void
148CrashGenerationServer::SetPath(const char* dump_path)
149{
150 pthread_mutex_lock(&dump_dir_mutex_);
151 this->dump_dir_ = string(dump_path);
152 pthread_mutex_unlock(&dump_dir_mutex_);
153}
154
155//static
156bool
157CrashGenerationServer::CreateReportChannel(int* server_fd, int* client_fd)
158{
159 int fds[2];
160
161 if (socketpair(AF_UNIX1, SOCK_SEQPACKETSOCK_SEQPACKET, 0, fds))
162 return false;
163
164 static const int on = 1;
165 // Enable passcred on the server end of the socket
166 if (setsockopt(fds[1], SOL_SOCKET1, SO_PASSCRED16, &on, sizeof(on)))
167 return false;
168
169 if (fcntl(fds[1], F_SETFL4, O_NONBLOCK04000))
170 return false;
171
172 *client_fd = fds[0];
173 *server_fd = fds[1];
174 return true;
175}
176
177// The following methods/functions execute on the server thread
178
179void
180CrashGenerationServer::Run()
181{
182 struct pollfd pollfds[2];
183 memset(&pollfds, 0, sizeof(pollfds));
184
185 pollfds[0].fd = server_fd_;
186 pollfds[0].events = POLLIN0x001;
187
188 pollfds[1].fd = control_pipe_in_;
189 pollfds[1].events = POLLIN0x001;
190
191 while (true) {
192 // infinite timeout
193 int nevents = poll(pollfds, sizeof(pollfds)/sizeof(pollfds[0]), -1);
194 if (-1 == nevents) {
195 if (EINTR4 == errno(*__errno_location ())) {
196 continue;
197 } else {
198 return;
199 }
200 }
201
202 if (pollfds[0].revents && !ClientEvent(pollfds[0].revents))
203 return;
204
205 if (pollfds[1].revents && !ControlEvent(pollfds[1].revents))
206 return;
207 }
208}
209
210static bool SendActionToClient(
211 int server_endpoint,
212 pid_t crashing_pid,
213 GenerationClientAction action
214);
215
216bool
217CrashGenerationServer::ClientEvent(short revents)
218{
219 if (POLLHUP0x010 & revents)
220 return false;
221 assert(POLLIN & revents)(static_cast <bool> (0x001 & revents) ? void (0) : __assert_fail
("POLLIN & revents", __builtin_FILE (), __builtin_LINE (
), __extension__ __PRETTY_FUNCTION__))
;
222
223 // A process has crashed and has signaled us by writing a datagram
224 // to the death signal socket. The datagram contains the crash context needed
225 // for writing the minidump as well as a file descriptor and a credentials
226 // block so that they can't lie about their pid.
227
228 // The length of the control message:
229 static const unsigned kControlMsgSize =
230 CMSG_SPACE(sizeof(int))((((sizeof(int)) + sizeof (size_t) - 1) & (size_t) ~(sizeof
(size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof (size_t
) - 1) & (size_t) ~(sizeof (size_t) - 1)))
+ CMSG_SPACE(sizeof(struct ucred))((((sizeof(struct ucred)) + sizeof (size_t) - 1) & (size_t
) ~(sizeof (size_t) - 1)) + (((sizeof (struct cmsghdr)) + sizeof
(size_t) - 1) & (size_t) ~(sizeof (size_t) - 1)))
;
231 // The length of the regular payload:
232 static const unsigned kCrashContextSize =
233 sizeof(google_breakpad::ExceptionHandler::CrashContext);
234
235 struct msghdr msg = {0};
236 struct iovec iov[1];
237 alignas(16) char crash_context[kCrashContextSize];
238 char control[kControlMsgSize];
239 const ssize_t expected_msg_size = sizeof(crash_context);
240
241 iov[0].iov_base = crash_context;
242 iov[0].iov_len = sizeof(crash_context);
243 msg.msg_iov = iov;
244 msg.msg_iovlen = sizeof(iov)/sizeof(iov[0]);
245 msg.msg_control = control;
246 msg.msg_controllen = kControlMsgSize;
247
248 const ssize_t msg_size = HANDLE_EINTR(recvmsg(server_fd_, &msg, 0))({ __typeof__(recvmsg(server_fd_, &msg, 0)) eintr_wrapper_result
; do { eintr_wrapper_result = (recvmsg(server_fd_, &msg, 0
)); } while (eintr_wrapper_result == -1 && (*__errno_location
()) == 4); eintr_wrapper_result; })
;
249 if (msg_size != expected_msg_size)
250 return true;
251
252 if (msg.msg_controllen != kControlMsgSize ||
253 msg.msg_flags & ~MSG_TRUNCMSG_TRUNC)
254 return true;
255
256 // Walk the control payload and extract the file descriptor and validated pid.
257 pid_t crashing_pid = -1;
258 [[maybe_unused]] uid_t crashing_uid = 0;
259 UniqueFd server_endpoint;
260 for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg)((size_t) (&msg)->msg_controllen >= sizeof (struct cmsghdr
) ? (struct cmsghdr *) (&msg)->msg_control : (struct cmsghdr
*) 0)
; hdr;
261 hdr = CMSG_NXTHDR(&msg, hdr)__cmsg_nxthdr (&msg, hdr)) {
262 if (hdr->cmsg_level != SOL_SOCKET1)
263 continue;
264 if (hdr->cmsg_type == SCM_RIGHTSSCM_RIGHTS) {
265 const unsigned len = hdr->cmsg_len -
266 (((uint8_t*)CMSG_DATA(hdr)((hdr)->__cmsg_data)) - (uint8_t*)hdr);
267 assert(len % sizeof(int) == 0u)(static_cast <bool> (len % sizeof(int) == 0u) ? void (0
) : __assert_fail ("len % sizeof(int) == 0u", __builtin_FILE (
), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__))
;
268 const unsigned num_fds = len / sizeof(int);
269 if (num_fds > 1 || num_fds == 0) {
270 // A nasty process could try and send us too many descriptors and
271 // force a leak.
272 for (unsigned i = 0; i < num_fds; ++i)
273 close(reinterpret_cast<int*>(CMSG_DATA(hdr)((hdr)->__cmsg_data))[i]);
274 return true;
275 } else {
276 server_endpoint.reset(*reinterpret_cast<int*>(CMSG_DATA(hdr)((hdr)->__cmsg_data)));
277 }
278 } else if (hdr->cmsg_type == SCM_CREDENTIALSSCM_CREDENTIALS) {
279 const struct ucred *cred =
280 reinterpret_cast<struct ucred*>(CMSG_DATA(hdr)((hdr)->__cmsg_data));
281 crashing_pid = cred->pid;
282 crashing_uid = cred->uid;
283 }
284 }
285
286 if (crashing_pid == -1 || !server_endpoint) {
287 return true;
288 }
289
290 string minidump_filename;
291 if (!MakeMinidumpFilename(minidump_filename))
292 return true;
293
294#if defined(MOZ_OXIDIZED_BREAKPAD1)
295 ExceptionHandler::CrashContext* breakpad_cc =
296 reinterpret_cast<ExceptionHandler::CrashContext*>(crash_context);
297 ExtraCrashData* extra_data = nullptr;
298 siginfo_t& si = breakpad_cc->siginfo;
299 signalfd_siginfo signalfd_si = {};
300 signalfd_si.ssi_signo = si.si_signo;
301 signalfd_si.ssi_errno = si.si_errno;
302 signalfd_si.ssi_code = si.si_code;
303 signalfd_si.ssi_pid = si.si_pid_sifields._kill.si_pid;
304 signalfd_si.ssi_uid = si.si_uid_sifields._kill.si_uid;
305
306 switch (si.si_signo) {
307 case SIGILL4:
308 case SIGFPE8:
309 case SIGSEGV11:
310 case SIGBUS7:
311 case SIGSYS31:
312 signalfd_si.ssi_addr = reinterpret_cast<size_t>(si.si_addr_sifields._sigfault.si_addr);
313 break;
314 }
315
316 UniqueFd remote_minidump_writer_endpoint;
317
318 // Different UID usually prevents direct ptrace()
319 if (force_remote_executor_ || crashing_uid != getuid()) {
320 if (!SendActionToClient(
321 server_endpoint.get(),
322 crashing_pid,
323 GenerationClientAction::ForkAndLaunchExecutor)) {
324 return true;
325 }
326
327 // From this point forward, the server endpoint is done with its job.
328 // It is now the endpoint for talking to the remote executor.
329 remote_minidump_writer_endpoint = std::move(server_endpoint);
330 }
331
332 bool res = false;
333
334 MinidumpWriterContext* writer = minidump_writer_create(
335 minidump_filename.c_str(),
336 crashing_pid,
337 breakpad_cc->tid,
338 &extra_data
339 );
340 DirectAuxvDumpInfo auxvInfo = {};
341 if (writer && get_auxv_info_ && get_auxv_info_(crashing_pid, &auxvInfo)) {
342 minidump_writer_set_direct_auxv_dump_info(writer, &auxvInfo);
343 }
344 if (writer) {
345 const fpregset_t *float_state = nullptr;
346
347# ifndef __arm__
348 float_state = reinterpret_cast<const fpregset_t *>(&breakpad_cc->float_state);
349# endif
350
351 minidump_writer_set_crash_context(writer, &breakpad_cc->context, float_state, &signalfd_si);
352
353 if (remote_minidump_writer_endpoint) {
354 // Pass ownership of the endpoint to the minidump-writer
355 minidump_writer_set_remote_unix_stream(writer, remote_minidump_writer_endpoint.release());
356 }
357
358 res = minidump_writer_dump(writer, extra_data);
Value stored to 'res' is never read
359 }
360#else
361 if (!google_breakpad::WriteMinidump(minidump_filename.c_str(),
362 crashing_pid, crash_context,
363 kCrashContextSize)) {
364 return true;
365 }
366#endif
367
368 ClientInfo info(crashing_pid, this, extra_data);
369 extra_data = nullptr; // ownership transferred to the info object.
370
371 if (dump_callback_) {
372 dump_callback_(dump_context_, info, minidump_filename);
373 }
374
375 // Close the endpoint, which will release a direct client and do nothing in the case of
376 // a remote client.
377 server_endpoint.reset();
378
379 return true;
380}
381
382bool
383CrashGenerationServer::ControlEvent(short revents)
384{
385 if (POLLHUP0x010 & revents)
386 return false;
387 assert(POLLIN & revents)(static_cast <bool> (0x001 & revents) ? void (0) : __assert_fail
("POLLIN & revents", __builtin_FILE (), __builtin_LINE (
), __extension__ __PRETTY_FUNCTION__))
;
388
389 char command;
390 if (read(control_pipe_in_, &command, 1))
391 return false;
392
393 switch (command) {
394 case kCommandQuit:
395 return false;
396 default:
397 assert(0)(static_cast <bool> (0) ? void (0) : __assert_fail ("0"
, __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__
))
;
398 }
399
400 return true;
401}
402
403bool
404CrashGenerationServer::MakeMinidumpFilename(string& outFilename)
405{
406 GUID guid;
407 char guidString[kGUIDStringLength+1];
408
409 if (!(CreateGUID(&guid)
410 && GUIDToString(&guid, guidString, sizeof(guidString))))
411 return false;
412
413 char path[PATH_MAX4096];
414 pthread_mutex_lock(&dump_dir_mutex_);
415 snprintf(path, sizeof(path), "%s/%s.dmp", dump_dir_.c_str(), guidString);
416 pthread_mutex_unlock(&dump_dir_mutex_);
417
418 outFilename = path;
419 return true;
420}
421
422static bool SendActionToClient(
423 int server_endpoint,
424 pid_t crashing_pid,
425 GenerationClientAction action
426) {
427 const uint8_t action_byte = static_cast<uint8_t>(action);
428
429 // MSG_DONTWAIT in case the client maliciously tries to freeze us by filling their buffer
430 const ssize_t rv = HANDLE_EINTR(send(({ __typeof__(send( server_endpoint, &action_byte, sizeof
(action_byte), MSG_NOSIGNAL | MSG_DONTWAIT)) eintr_wrapper_result
; do { eintr_wrapper_result = (send( server_endpoint, &action_byte
, sizeof(action_byte), MSG_NOSIGNAL | MSG_DONTWAIT)); } while
(eintr_wrapper_result == -1 && (*__errno_location ()
) == 4); eintr_wrapper_result; })
431 server_endpoint, &action_byte, sizeof(action_byte), MSG_NOSIGNAL | MSG_DONTWAIT))({ __typeof__(send( server_endpoint, &action_byte, sizeof
(action_byte), MSG_NOSIGNAL | MSG_DONTWAIT)) eintr_wrapper_result
; do { eintr_wrapper_result = (send( server_endpoint, &action_byte
, sizeof(action_byte), MSG_NOSIGNAL | MSG_DONTWAIT)); } while
(eintr_wrapper_result == -1 && (*__errno_location ()
) == 4); eintr_wrapper_result; })
;
432 if (rv == static_cast<ssize_t>(sizeof(action_byte))) {
433 return true;
434 }
435
436 char err_msg[256];
437 if (rv == -1) {
438 const int error_code = errno(*__errno_location ());
439 snprintf(err_msg, sizeof(err_msg),
440 "CrashGenerationServer failed to send action %hhu to process %d. Errno %d.\n",
441 action_byte,
442 static_cast<int>(crashing_pid), error_code);
443 } else {
444 snprintf(err_msg, sizeof(err_msg),
445 "CrashGenerationServer failed to send action %hhu to process %d with no error.\n",
446 action_byte,
447 static_cast<int>(crashing_pid));
448 }
449
450 logger::write(err_msg, strlen(err_msg));
451 return false;
452}
453
454} // namespace google_breakpad