• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tstack / lnav / 19243988760-2657

10 Nov 2025 07:37PM UTC coverage: 68.747% (-0.3%) from 69.055%
19243988760-2657

push

github

tstack
[logfile] lay groundwork for bounding log file times

Related to #1188

308 of 655 new or added lines in 35 files covered. (47.02%)

30 existing lines in 7 files now uncovered.

50645 of 73669 relevant lines covered (68.75%)

430651.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

72.27
/src/shared_buffer.cc
1
/**
2
 * Copyright (c) 2014, Timothy Stack
3
 *
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions are met:
8
 *
9
 * * Redistributions of source code must retain the above copyright notice, this
10
 * list of conditions and the following disclaimer.
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 * this list of conditions and the following disclaimer in the documentation
13
 * and/or other materials provided with the distribution.
14
 * * Neither the name of Timothy Stack nor the names of its contributors
15
 * may be used to endorse or promote products derived from this software
16
 * without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
19
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
22
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * @file shared_buffer.cc
30
 */
31

32
#include "config.h"
33

34
#ifdef HAVE_EXECINFO_H
35
// clang-format off
36
#    include <sys/types.h>
37
// clang-format on
38

39
#    include <execinfo.h>
40
#endif
41

42
#include <algorithm>
43

44
#include "base/ansi_scrubber.hh"
45
#include "shared_buffer.hh"
46

47
void
48
shared_buffer_ref::share(shared_buffer& sb, const char* data, size_t len)
110,695✔
49
{
50
#if SHARED_BUFFER_TRACE
51
    void* frames[128];
52
    int rc;
53

54
    rc = backtrace(frames, 128);
55
    this->sb_backtrace.reset(backtrace_symbols(frames, rc));
56
#endif
57

58
    this->disown();
110,695✔
59

60
    sb.add_ref(*this);
110,695✔
61
    this->sb_owner = &sb;
110,695✔
62
    this->sb_data = data;
110,695✔
63
    this->sb_length = len;
110,695✔
64

65
    ensure(this->sb_length < (10 * 1024 * 1024));
110,695✔
66
}
110,695✔
67

68
bool
UNCOV
69
shared_buffer_ref::subset(shared_buffer_ref& other, off_t offset, size_t len)
×
70
{
UNCOV
71
    this->disown();
×
72

UNCOV
73
    if (offset != -1) {
×
UNCOV
74
        this->sb_owner = other.sb_owner;
×
UNCOV
75
        this->sb_length = len;
×
UNCOV
76
        if (this->sb_owner == nullptr) {
×
77
            if ((this->sb_data = (char*) malloc(this->sb_length)) == nullptr) {
×
78
                return false;
×
79
            }
80

81
            memcpy(
×
82
                const_cast<char*>(this->sb_data), &other.sb_data[offset], len);
×
83
        } else {
UNCOV
84
            this->sb_owner->add_ref(*this);
×
UNCOV
85
            this->sb_data = &other.sb_data[offset];
×
86
        }
87
    }
UNCOV
88
    return true;
×
89
}
90

91
shared_buffer_ref::
530,543✔
92
shared_buffer_ref(shared_buffer_ref&& other) noexcept
530,543✔
93
{
94
    if (other.sb_data == nullptr) {
530,543✔
95
        this->sb_owner = nullptr;
×
96
        this->sb_data = nullptr;
×
97
        this->sb_length = 0;
×
98
    } else if (other.sb_owner != nullptr) {
530,543✔
99
        auto owner_ref_iter = std::find(other.sb_owner->sb_refs.rbegin(),
530,513✔
100
                                        other.sb_owner->sb_refs.rend(),
1,061,026✔
101
                                        &other);
1,061,026✔
102
        *owner_ref_iter = this;
530,513✔
103
        this->sb_owner = std::exchange(other.sb_owner, nullptr);
530,513✔
104
        this->sb_data = std::exchange(other.sb_data, nullptr);
530,513✔
105
        this->sb_length = std::exchange(other.sb_length, 0);
530,513✔
106
    } else {
107
        this->sb_owner = nullptr;
30✔
108
        this->sb_data = other.sb_data;
30✔
109
        this->sb_length = other.sb_length;
30✔
110
        other.sb_data = nullptr;
30✔
111
        other.sb_length = 0;
30✔
112
    }
113
    this->sb_metadata = other.sb_metadata;
530,543✔
114
    other.sb_metadata = {};
530,543✔
115
}
530,543✔
116

117
shared_buffer_ref&
118
shared_buffer_ref::operator=(shared_buffer_ref&& other) noexcept
40,808✔
119
{
120
    this->disown();
40,808✔
121

122
    if (other.sb_data == nullptr) {
40,808✔
123
        this->sb_owner = nullptr;
×
124
        this->sb_data = nullptr;
×
125
        this->sb_length = 0;
×
126
    } else if (other.sb_owner != nullptr) {
40,808✔
127
        auto owner_ref_iter = std::find(other.sb_owner->sb_refs.rbegin(),
40,808✔
128
                                        other.sb_owner->sb_refs.rend(),
81,616✔
129
                                        &other);
81,616✔
130
        *owner_ref_iter = this;
40,808✔
131
        this->sb_owner = std::exchange(other.sb_owner, nullptr);
40,808✔
132
        this->sb_data = std::exchange(other.sb_data, nullptr);
40,808✔
133
        this->sb_length = std::exchange(other.sb_length, 0);
40,808✔
134
    } else {
135
        this->sb_owner = nullptr;
×
136
        this->sb_data = other.sb_data;
×
137
        this->sb_length = other.sb_length;
×
138
        other.sb_data = nullptr;
×
139
        other.sb_length = 0;
×
140
    }
141
    this->sb_metadata = other.sb_metadata;
40,808✔
142
    other.sb_metadata = {};
40,808✔
143

144
    return *this;
40,808✔
145
}
146

147
bool
148
shared_buffer_ref::take_ownership(size_t length)
3,044✔
149
{
150
    if ((this->sb_owner != nullptr && this->sb_data != nullptr)
3,044✔
151
        || this->sb_length != length)
×
152
    {
153
        auto* new_data = (char*) malloc(length);
3,044✔
154
        if (new_data == nullptr) {
3,044✔
155
            return false;
×
156
        }
157

158
        memcpy(new_data, this->sb_data, std::min(length, this->sb_length));
3,044✔
159
        this->sb_length = length;
3,044✔
160
        this->sb_data = new_data;
3,044✔
161
        this->sb_owner->sb_refs.erase(find(this->sb_owner->sb_refs.begin(),
3,044✔
162
                                           this->sb_owner->sb_refs.end(),
3,044✔
163
                                           this));
3,044✔
164
        this->sb_owner = nullptr;
3,044✔
165
    }
166
    return true;
3,044✔
167
}
168

169
void
170
shared_buffer_ref::disown()
924,877✔
171
{
172
    if (this->sb_owner == nullptr) {
924,877✔
173
        if (this->sb_data != nullptr) {
817,226✔
174
            free(const_cast<char*>(this->sb_data));
3,047✔
175
        }
176
    } else {
177
        this->sb_owner->sb_refs.erase(find(this->sb_owner->sb_refs.begin(),
107,651✔
178
                                           this->sb_owner->sb_refs.end(),
107,651✔
179
                                           this));
215,302✔
180
    }
181
    this->sb_owner = nullptr;
924,877✔
182
    this->sb_data = nullptr;
924,877✔
183
    this->sb_length = 0;
924,877✔
184
    this->sb_metadata = {};
924,877✔
185
}
924,877✔
186

187
void
188
shared_buffer_ref::copy_ref(const shared_buffer_ref& other)
8,088✔
189
{
190
    if (other.sb_data == nullptr) {
8,088✔
191
        this->sb_owner = nullptr;
793✔
192
        this->sb_data = nullptr;
793✔
193
        this->sb_length = 0;
793✔
194
    } else if (other.sb_owner != nullptr) {
7,295✔
195
        this->share(*other.sb_owner, other.sb_data, other.sb_length);
7,292✔
196
    } else {
197
        this->sb_owner = nullptr;
3✔
198
        this->sb_data = (char*) malloc(other.sb_length);
3✔
199
        memcpy(
3✔
200
            const_cast<char*>(this->sb_data), other.sb_data, other.sb_length);
3✔
201
        this->sb_length = other.sb_length;
3✔
202
    }
203
    this->sb_metadata = other.sb_metadata;
8,088✔
204
}
8,088✔
205

206
shared_buffer_ref::narrow_result
UNCOV
207
shared_buffer_ref::narrow(size_t new_data, size_t new_length)
×
208
{
UNCOV
209
    return std::make_pair(
×
UNCOV
210
        std::exchange(this->sb_data, this->sb_data + new_data),
×
UNCOV
211
        std::exchange(this->sb_length, new_length));
×
212
}
213

214
void
UNCOV
215
shared_buffer_ref::widen(narrow_result old_data_length)
×
216
{
UNCOV
217
    this->sb_data = old_data_length.first;
×
UNCOV
218
    this->sb_length = old_data_length.second;
×
219
}
220

221
void
222
shared_buffer_ref::erase_ansi()
43,625✔
223
{
224
    if (!this->sb_metadata.m_valid_utf || !this->sb_metadata.m_has_ansi) {
43,625✔
225
        return;
43,429✔
226
    }
227

228
    auto* writable_data = this->get_writable_data();
196✔
229
    auto new_len = erase_ansi_escapes(
196✔
230
        string_fragment::from_bytes(writable_data, this->sb_length));
231

232
    this->sb_length = new_len;
196✔
233
    this->sb_metadata.m_has_ansi = false;
196✔
234
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc