• 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 <securec.h>
24 #include <unistd.h>
25 
26 #include "dfx_define.h"
27 #include "dfx_exception.h"
28 #include "errno.h"
29 #include "string.h"
30 #include "dfx_log.h"
31 
32 #ifdef LOG_DOMAIN
33 #undef LOG_DOMAIN
34 #define LOG_DOMAIN 0xD002D11
35 #endif
36 
37 #ifdef LOG_TAG
38 #undef LOG_TAG
39 #define LOG_TAG "DfxSignalHandlerException"
40 #endif
41 
42 static const int TIME_OUT = 2;       /* socket connecet timeout 2 seconds */
43 const char * const FAULTLOGGERD_SOCKET_NAME = "/dev/unix/socket/faultloggerd.server";
44 
ConnectSocket(const char * path,const int timeout)45 static int ConnectSocket(const char* path, const int timeout)
46 {
47     int fd = -1;
48     if ((fd = syscall(SYS_socket, AF_LOCAL, SOCK_STREAM, 0)) < 0) {
49         DFXLOGE("Failed to create a socket, errno(%{public}d).", errno);
50         return -1;
51     }
52 
53     do {
54         if (timeout > 0) {
55             struct timeval timev = {
56                 timeout,
57                 0
58             };
59             void* pTimev = &timev;
60             if (OHOS_TEMP_FAILURE_RETRY(syscall(SYS_setsockopt, fd, SOL_SOCKET, SO_RCVTIMEO,
61                 (const void*)(pTimev), sizeof(timev))) != 0) {
62                 DFXLOGE("setsockopt SO_RCVTIMEO error, errno(%{public}d).", errno);
63                 syscall(SYS_close, fd);
64                 fd = -1;
65                 break;
66             }
67         }
68         struct sockaddr_un server;
69         (void)memset_s(&server, sizeof(server), 0, sizeof(server));
70         server.sun_family = AF_LOCAL;
71         if (strcpy_s(server.sun_path, sizeof(server.sun_path), path) != EOK) {
72             DFXLOGE("server sun_path strcpy fail.");
73         }
74         int len = sizeof(server.sun_family) + strlen(server.sun_path);
75         int connected = OHOS_TEMP_FAILURE_RETRY(connect(fd, (struct sockaddr*)(&server), len));
76         if (connected < 0) {
77             DFXLOGE("Failed to connect to faultloggerd socket, errno = %{public}d.", errno);
78             syscall(SYS_close, fd);
79             fd = -1;
80             break;
81         }
82     } while (false);
83     return fd;
84 }
85 
ReportException(struct CrashDumpException * exception)86 int ReportException(struct CrashDumpException* exception)
87 {
88     if (exception == NULL) {
89         return -1;
90     }
91     exception->head.clientType = REPORT_EXCEPTION_CLIENT;
92     exception->head.clientPid = getpid();
93     int ret = -1;
94     int fd = ConnectSocket(FAULTLOGGERD_SOCKET_NAME, TIME_OUT); // connect timeout
95     if (fd == -1) {
96         DFXLOGE("Failed to connect socket.");
97         return ret;
98     }
99     do {
100         if (OHOS_TEMP_FAILURE_RETRY(write(fd, exception, sizeof(struct CrashDumpException))) !=
101             (long)sizeof(struct CrashDumpException)) {
102             DFXLOGE("Failed to write request message to socket, errno(%{public}d).", errno);
103             break;
104         }
105         ret = 0;
106     } while (false);
107     syscall(SYS_close, fd);
108     return ret;
109 }
110