• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (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
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "dfx_signalhandler_exception.h"
17 
18 #include <stdio.h>
19 #include <sys/syscall.h>
20 #include <sys/socket.h>
21 #include <sys/time.h>
22 #include <sys/un.h>
23 #include <unistd.h>
24 
25 #include "dfx_define.h"
26 #include "dfx_exception.h"
27 #include "errno.h"
28 #include "string.h"
29 
30 #ifndef DFX_SIGNAL_LIBC
31 #include "dfx_log.h"
32 #else
33 #include "musl_log.h"
34 #endif
35 
36 #ifdef LOG_DOMAIN
37 #undef LOG_DOMAIN
38 #define LOG_DOMAIN 0xD002D11
39 #endif
40 
41 #ifdef LOG_TAG
42 #undef LOG_TAG
43 #define LOG_TAG "DfxSignalHandlerException"
44 #endif
45 
46 static const int TIME_OUT = 2;       /* seconds */
47 static const char FAULTLOGGERD_SOCKET_NAME[] = "/dev/unix/socket/faultloggerd.server";
48 
ConnectSocket(const char * path,const int timeout)49 static int ConnectSocket(const char* path, const int timeout)
50 {
51     int fd = -1;
52     if ((fd = syscall(SYS_socket, AF_LOCAL, SOCK_STREAM, 0)) < 0) {
53         DFXLOGE("Failed to create a socket, errno(%{public}d).", errno);
54         return -1;
55     }
56 
57     do {
58         if (timeout > 0) {
59             struct timeval timev = {
60                 timeout,
61                 0
62             };
63             void* pTimev = &timev;
64             if (OHOS_TEMP_FAILURE_RETRY(syscall(SYS_setsockopt, fd, SOL_SOCKET, SO_RCVTIMEO,
65                 (const void*)(pTimev), sizeof(timev))) != 0) {
66                 DFXLOGE("setsockopt SO_RCVTIMEO error, errno(%{public}d).", errno);
67                 syscall(SYS_close, fd);
68                 fd = -1;
69                 break;
70             }
71         }
72         struct sockaddr_un server;
73         (void)memset(&server, 0, sizeof(server));
74         server.sun_family = AF_LOCAL;
75         (void)strncpy(server.sun_path, path, sizeof(server.sun_path) - 1);
76         int len = sizeof(server.sun_family) + strlen(server.sun_path);
77         int connected = OHOS_TEMP_FAILURE_RETRY(connect(fd, (struct sockaddr*)(&server), len));
78         if (connected < 0) {
79             DFXLOGE("Failed to connect to faultloggerd socket, errno = %{public}d.", errno);
80             syscall(SYS_close, fd);
81             fd = -1;
82             break;
83         }
84     } while (false);
85     return fd;
86 }
87 
ReportException(struct CrashDumpException * exception)88 int ReportException(struct CrashDumpException* exception)
89 {
90     if (exception == NULL) {
91         return -1;
92     }
93     exception->head.clientType = REPORT_EXCEPTION_CLIENT;
94     exception->head.clientPid = getpid();
95     int ret = -1;
96     int fd = ConnectSocket(FAULTLOGGERD_SOCKET_NAME, TIME_OUT); // connect timeout
97     if (fd == -1) {
98         DFXLOGE("Failed to connect socket.");
99         return ret;
100     }
101     do {
102         if (OHOS_TEMP_FAILURE_RETRY(write(fd, exception, sizeof(struct CrashDumpException))) !=
103             (long)sizeof(struct CrashDumpException)) {
104             DFXLOGE("Failed to write request message to socket, errno(%{public}d).", errno);
105             break;
106         }
107         ret = 0;
108     } while (false);
109     syscall(SYS_close, fd);
110     return ret;
111 }
112