blob: 1a2695e1caf34af2024cc0862bdd51d046fb3f64 [file] [log] [blame]
Mark Salyzyn12bac902014-02-26 09:50:16 -08001/*
2 * Copyright (C) 2012-2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Tom Cherry479b5032020-05-07 14:44:43 -070017#include "LogBufferElement.h"
18
Mark Salyzynbf918322015-04-20 07:26:27 -070019#include <ctype.h>
Mark Salyzyna69d5a42015-03-16 12:04:09 -070020#include <endian.h>
Mark Salyzynbf918322015-04-20 07:26:27 -070021#include <fcntl.h>
Mark Salyzyn12bac902014-02-26 09:50:16 -080022#include <stdio.h>
23#include <string.h>
24#include <time.h>
25#include <unistd.h>
26
Tom Cherry1e2ebe32020-04-17 09:38:55 -070027#include <log/log_read.h>
Mark Salyzyna69d5a42015-03-16 12:04:09 -070028#include <private/android_logger.h>
Mark Salyzyn12bac902014-02-26 09:50:16 -080029
Tom Cherry0281b202020-05-12 13:16:41 -070030#include "LogStatistics.h"
Mark Salyzyn1d21d542016-02-23 08:55:43 -080031#include "LogUtils.h"
Mark Salyzyn12bac902014-02-26 09:50:16 -080032
Tom Cherryac228f12019-08-21 14:16:34 -070033LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
Tom Cherry0bf66db2020-05-21 13:56:33 -070034 pid_t tid, uint64_t sequence, const char* msg, uint16_t len)
Tom Cherryf1910142020-05-19 19:01:16 -070035 : uid_(uid),
36 pid_(pid),
37 tid_(tid),
38 sequence_(sequence),
39 realtime_(realtime),
40 msg_len_(len),
Elliott Hughes225e5c62022-09-16 23:01:59 +000041 log_id_(log_id) {
Tom Cherryf1910142020-05-19 19:01:16 -070042 msg_ = new char[len];
43 memcpy(msg_, msg, len);
Mark Salyzyn12bac902014-02-26 09:50:16 -080044}
45
Mark Salyzyn65059532017-03-10 14:31:54 -080046LogBufferElement::LogBufferElement(const LogBufferElement& elem)
Tom Cherryf1910142020-05-19 19:01:16 -070047 : uid_(elem.uid_),
48 pid_(elem.pid_),
49 tid_(elem.tid_),
50 sequence_(elem.sequence_),
51 realtime_(elem.realtime_),
52 msg_len_(elem.msg_len_),
Elliott Hughes225e5c62022-09-16 23:01:59 +000053 log_id_(elem.log_id_) {
54 msg_ = new char[msg_len_];
55 memcpy(msg_, elem.msg_, msg_len_);
Mark Salyzyn24a57dc2016-12-13 10:31:29 -080056}
57
Tom Cherry17b77582020-06-17 11:40:55 -070058LogBufferElement::LogBufferElement(LogBufferElement&& elem) noexcept
Tom Cherryf1910142020-05-19 19:01:16 -070059 : uid_(elem.uid_),
60 pid_(elem.pid_),
61 tid_(elem.tid_),
62 sequence_(elem.sequence_),
63 realtime_(elem.realtime_),
64 msg_len_(elem.msg_len_),
Elliott Hughes225e5c62022-09-16 23:01:59 +000065 log_id_(elem.log_id_) {
66 msg_ = elem.msg_;
67 elem.msg_ = nullptr;
Tom Cherry11458452020-05-19 18:02:00 -070068}
69
Mark Salyzyn12bac902014-02-26 09:50:16 -080070LogBufferElement::~LogBufferElement() {
Elliott Hughes225e5c62022-09-16 23:01:59 +000071 delete[] msg_;
Mark Salyzyn12bac902014-02-26 09:50:16 -080072}
73
Tom Cherryf1910142020-05-19 19:01:16 -070074uint32_t LogBufferElement::GetTag() const {
Tom Cherryc967fe12019-08-23 09:09:40 -070075 // Binary buffers have no tag.
Tom Cherry8f459112020-06-02 15:39:21 -070076 if (!IsBinary(log_id())) {
Tom Cherryc967fe12019-08-23 09:09:40 -070077 return 0;
78 }
Tom Cherry8f459112020-06-02 15:39:21 -070079 return MsgToTag(msg(), msg_len());
80}
Tom Cherryc967fe12019-08-23 09:09:40 -070081
Tom Cherry8f459112020-06-02 15:39:21 -070082LogStatisticsElement LogBufferElement::ToLogStatisticsElement() const {
Tom Cherrya3d6aa62020-06-19 12:21:21 -070083 // Estimate the size of this element in the parent std::list<> by adding two void*'s
84 // corresponding to the next/prev pointers and aligning to 64 bit.
85 uint16_t element_in_list_size =
86 (sizeof(*this) + 2 * sizeof(void*) + sizeof(uint64_t) - 1) & -sizeof(uint64_t);
Tom Cherry8f459112020-06-02 15:39:21 -070087 return LogStatisticsElement{
88 .uid = uid(),
89 .pid = pid(),
90 .tid = tid(),
91 .tag = GetTag(),
92 .realtime = realtime(),
93 .msg = msg(),
94 .msg_len = msg_len(),
Tom Cherry8f459112020-06-02 15:39:21 -070095 .log_id = log_id(),
Tom Cherrya3d6aa62020-06-19 12:21:21 -070096 .total_len = static_cast<uint16_t>(element_in_list_size + msg_len()),
Tom Cherry8f459112020-06-02 15:39:21 -070097 };
Christopher Ferrisdddc2892017-08-02 17:54:27 -070098}
99
Mark Salyzynbf918322015-04-20 07:26:27 -0700100// caller must own and free character string
Mark Salyzyn65059532017-03-10 14:31:54 -0800101char* android::tidToName(pid_t tid) {
Yi Kong36feb152018-07-13 17:39:22 -0700102 char* retval = nullptr;
Mark Salyzynbf918322015-04-20 07:26:27 -0700103 char buffer[256];
104 snprintf(buffer, sizeof(buffer), "/proc/%u/comm", tid);
Tom Cherry17b77582020-06-17 11:40:55 -0700105 int fd = open(buffer, O_RDONLY | O_CLOEXEC);
Mark Salyzynbf918322015-04-20 07:26:27 -0700106 if (fd >= 0) {
107 ssize_t ret = read(fd, buffer, sizeof(buffer));
108 if (ret >= (ssize_t)sizeof(buffer)) {
109 ret = sizeof(buffer) - 1;
110 }
111 while ((ret > 0) && isspace(buffer[ret - 1])) {
112 --ret;
113 }
114 if (ret > 0) {
115 buffer[ret] = '\0';
116 retval = strdup(buffer);
117 }
118 close(fd);
Mark Salyzyna69d5a42015-03-16 12:04:09 -0700119 }
120
Mark Salyzynbf918322015-04-20 07:26:27 -0700121 // if nothing for comm, check out cmdline
Mark Salyzyn65059532017-03-10 14:31:54 -0800122 char* name = android::pidToName(tid);
Mark Salyzynbf918322015-04-20 07:26:27 -0700123 if (!retval) {
124 retval = name;
Yi Kong36feb152018-07-13 17:39:22 -0700125 name = nullptr;
Mark Salyzynbf918322015-04-20 07:26:27 -0700126 }
127
128 // check if comm is truncated, see if cmdline has full representation
129 if (name) {
130 // impossible for retval to be NULL if name not NULL
131 size_t retval_len = strlen(retval);
132 size_t name_len = strlen(name);
133 // KISS: ToDo: Only checks prefix truncated, not suffix, or both
Mark Salyzyn65059532017-03-10 14:31:54 -0800134 if ((retval_len < name_len) &&
135 !fastcmp<strcmp>(retval, name + name_len - retval_len)) {
Mark Salyzynbf918322015-04-20 07:26:27 -0700136 free(retval);
137 retval = name;
138 } else {
139 free(name);
140 }
141 }
142 return retval;
143}
144
Elliott Hughes225e5c62022-09-16 23:01:59 +0000145bool LogBufferElement::FlushTo(LogWriter* writer) {
Tom Cherry47856dd2019-10-15 16:53:11 -0700146 struct logger_entry entry = {};
Mark Salyzyna69d5a42015-03-16 12:04:09 -0700147
Tom Cherry47856dd2019-10-15 16:53:11 -0700148 entry.hdr_size = sizeof(struct logger_entry);
Tom Cherryf1910142020-05-19 19:01:16 -0700149 entry.lid = log_id_;
150 entry.pid = pid_;
151 entry.tid = tid_;
152 entry.uid = uid_;
153 entry.sec = realtime_.tv_sec;
154 entry.nsec = realtime_.tv_nsec;
Elliott Hughes225e5c62022-09-16 23:01:59 +0000155 entry.len = msg_len_;
Mark Salyzyn12bac902014-02-26 09:50:16 -0800156
Elliott Hughes225e5c62022-09-16 23:01:59 +0000157 return writer->Write(entry, msg_);
Mark Salyzyn12bac902014-02-26 09:50:16 -0800158}