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

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

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

3.03
/libs/core/debugging/src/print.cpp
1
//  Copyright (c) 2019-2020 John Biddiscombe
2
//
3
//  SPDX-License-Identifier: BSL-1.0
4
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
5
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6

7
#include <hpx/config.hpp>
8
#include <hpx/debugging/environ.hpp>
9
#include <hpx/debugging/print.hpp>
10

11
#include <algorithm>
12
#include <array>
13
#include <atomic>
14
#include <bitset>
15
#include <chrono>
16
#include <climits>
17
#include <cmath>
18
#include <cstddef>
19
#include <cstdint>
20
#include <cstring>
21
#include <functional>
22
#include <iomanip>
23
#include <iostream>
24
#include <iterator>
25
#include <string>
26
#include <thread>
27
#include <type_traits>
28
#include <utility>
29
#include <vector>
30

31
#if defined(__FreeBSD__)
32
HPX_CORE_EXPORT char** freebsd_environ = nullptr;
33
#endif
34
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
35
#include <winsock2.h>
36
#endif
37

38
// Used to wrap function call parameters to prevent evaluation
39
// when debugging is disabled
40
#define HPX_DP_LAZY(Expr, printer) printer.eval([&] { return Expr; })
41

42
// ------------------------------------------------------------
43
/// \cond NODETAIL
44
namespace hpx::debug {
45

46
    // ------------------------------------------------------------------
47
    // format as zero padded int
48
    // ------------------------------------------------------------------
×
49
    namespace detail {
50

51
        template <typename Int>
×
52
        void print_dec(std::ostream& os, Int const& v, int N)
×
53
        {
54
            os << std::right << std::setfill('0') << std::setw(N)
55
               << std::noshowbase << std::dec << v;
56
        }
57

58
        template void print_dec(std::ostream&, std::int16_t const&, int);
59
        template void print_dec(std::ostream&, std::uint16_t const&, int);
60
        template void print_dec(std::ostream&, std::int32_t const&, int);
61
        template void print_dec(std::ostream&, std::uint32_t const&, int);
62
        template void print_dec(std::ostream&, std::int64_t const&, int);
63
        template void print_dec(std::ostream&, std::uint64_t const&, int);
64
#if defined(__APPLE__)
65
        template void print_dec(std::ostream&, long const&, int);
66
        template void print_dec(std::ostream&, unsigned long const&, int);
67
#endif
68

69
        template void print_dec(std::ostream&, std::atomic<int> const&, int);
70
        template void print_dec(
71
            std::ostream&, std::atomic<unsigned int> const&, int);
72
    }    // namespace detail
×
73

×
74
    // ------------------------------------------------------------------
75
    // format as pointer
×
76
    // ------------------------------------------------------------------
77
    ptr::ptr(void const* v) noexcept
×
78
      : data_(v)
×
79
    {
80
    }
×
81

82
    ptr::ptr(std::uintptr_t v) noexcept
×
83
      : data_(reinterpret_cast<void const*>(v))
84
    {
×
85
    }
×
86

87
    std::ostream& operator<<(std::ostream& os, ptr const& d)
88
    {
89
        os << d.data_;
90
        return os;
91
    }
92

93
    // ------------------------------------------------------------------
94
    // format as zero padded hex
×
95
    // ------------------------------------------------------------------
96
    namespace detail {
97

×
98
        template <typename Int>
×
99
        void print_hex(std::ostream& os, Int v, int N)
100
        {
101
            os << std::right << "0x" << std::setfill('0') << std::setw(N)
102
               << std::noshowbase << std::hex << v;
103
        }
104

105
        template HPX_CORE_EXPORT void print_hex(
106
            std::ostream&, std::thread::id, int);
×
107
        template HPX_CORE_EXPORT void print_hex(
108
            std::ostream&, unsigned long, int);
109
        template HPX_CORE_EXPORT void print_hex(std::ostream&, int, int);
110

×
111
        void print_ptr(std::ostream& os, void const* v, int N)
112
        {
113
            os << std::right << std::setw(N) << std::noshowbase << std::hex
114
               << v;
115
        }
116

117
    }    // namespace detail
118

119
    // ------------------------------------------------------------------
120
    // format as binary bits
×
121
    // ------------------------------------------------------------------
122
    namespace detail {
123

124
        template <typename Int>
125
        HPX_CORE_EXPORT void print_bin(std::ostream& os, Int v, int N)
×
126
        {
×
127
            char const* beg = reinterpret_cast<char const*>(&v);
128
            char const* end = beg + sizeof(v);
×
129

130
            N = (N + CHAR_BIT - 1) / CHAR_BIT;
×
131
            while (beg != end && N-- > 0)
132
            {
133
                os << std::bitset<CHAR_BIT>(*beg++);
134
            }
135
        }
136

137
        template HPX_CORE_EXPORT void print_bin(
138
            std::ostream&, std::uint64_t, int);
139

140
#if defined(__APPLE__)
141
        // Explicit instantiation necessary to solve undefined symbol for MacOS
142
        template HPX_CORE_EXPORT void print_bin(
143
            std::ostream&, unsigned long, int);
144
#endif
145
    }    // namespace detail
146

147
    // ------------------------------------------------------------------
×
148
    // format as padded string
149
    // ------------------------------------------------------------------
×
150
    namespace detail {
×
151

152
        void print_str(std::ostream& os, char const* v, int N)
153
        {
154
            os << std::left << std::setfill(' ') << std::setw(N) << v;
155
        }
156
    }    // namespace detail
×
157

×
158
    // ------------------------------------------------------------------
×
159
    // format as ip address
160
    // ------------------------------------------------------------------
×
161
    ipaddr::ipaddr(void const* a) noexcept
162
      : data_(static_cast<std::uint8_t const*>(a))
×
163
      , ipdata_(0)
×
164
    {
×
165
    }
166

×
167
    ipaddr::ipaddr(std::uint32_t a) noexcept
168
      : data_(reinterpret_cast<uint8_t const*>(&ipdata_))    //-V206
×
169
      , ipdata_(a)
170
    {
×
171
    }
×
172

×
173
    std::ostream& operator<<(std::ostream& os, ipaddr const& p)
×
174
    {
×
175
        os << std::dec << static_cast<int>(p.data_[0]) << "."
176
           << static_cast<int>(p.data_[1]) << "."
177
           << static_cast<int>(p.data_[2]) << "."
178
           << static_cast<int>(p.data_[3]);
179
        return os;
180
    }
181

182
    // ------------------------------------------------------------------
×
183
    // helper class for printing time since start
184
    // ------------------------------------------------------------------
185
    namespace detail {
×
186

187
        std::ostream& operator<<(std::ostream& os, current_time_print_helper)
×
188
        {
189
            static std::chrono::steady_clock::time_point log_t_start =
190
                std::chrono::steady_clock::now();
191

×
192
            auto const now = std::chrono::steady_clock::now();    //-V656
193
            auto const nowt =
×
194
                std::chrono::duration_cast<std::chrono::microseconds>(
×
195
                    now - log_t_start)
196
                    .count();
197

198
            os << debug::dec<10>(nowt) << " ";
199
            return os;
200
        }
201
    }    // namespace detail
202

203
    ///////////////////////////////////////////////////////////////////////////
64✔
204
    namespace detail {
205

64✔
206
        std::function<void(std::ostream&)> print_info;
64✔
207

208
        void register_print_info(void (*printer)(std::ostream&))
×
209
        {
210
            print_info = printer;
×
211
        }
×
212

213
        void generate_prefix(std::ostream& os)
214
        {
215
            os << detail::current_time_print_helper();
×
216
            if (print_info)
×
217
            {
218
                print_info(os);
219
            }
220
            os << detail::hostname_print_helper();
221
        }
222

223
        void display_to_cout(std::string const& str)
224
        {
×
225
            std::cout << str;
×
226
        }
×
227
    }    // namespace detail
×
228

×
229
    // ------------------------------------------------------------------
230
    // helper function for printing short memory dump and crc32
×
231
    // useful for debugging corruptions in buffers during
232
    // rma or other transfers
×
233
    // ------------------------------------------------------------------
234
    mem_crc32::mem_crc32(
×
235
        void const* a, std::size_t len, char const* txt) noexcept
×
236
      : addr_(static_cast<std::uint64_t const*>(a))    //-V206
×
237
      , len_(len)
×
238
      , txt_(txt)
×
239
    {
240
    }
241

×
242
    std::ostream& operator<<(std::ostream& os, mem_crc32 const& p)
×
243
    {
×
244
        auto uintBuf = static_cast<std::uint64_t const*>(p.addr_);
×
245
        os << "Memory:";
246
        os << " address " << hpx::debug::ptr(p.addr_) << " length "
×
247
           << hpx::debug::hex<6>(p.len_)
248
           << " CRC32:" << hpx::debug::hex<8>(crc32(p.addr_, p.len_)) << "\n";
×
249

×
250
        auto const max_value =
251
            (std::min) (static_cast<std::size_t>(
252
                            std::ceil(static_cast<double>(p.len_) / 8.0)),
253
                static_cast<std::size_t>(128));
254
        for (std::size_t i = 0; i < max_value; i++)
255
        {
256
            os << hpx::debug::hex<16>(*uintBuf++) << " ";
257
        }
×
258
        os << " : " << p.txt_;
259
        return os;
260
    }
261

×
262
    namespace detail {
263

×
264
        // ------------------------------------------------------------------
265
        // helper class for printing time since start
×
266
        // ------------------------------------------------------------------
267
        [[nodiscard]] char const* hostname_print_helper::get_hostname() const
×
268
        {
×
269
            static bool initialized = false;
270
            static char hostname_[32] = {'\0'};
271
            if (!initialized)
272
            {
273
                initialized = true;
274
#if !defined(__FreeBSD__)
275
                gethostname(hostname_, static_cast<std::size_t>(12));
×
276
#endif
277
                int const rank = guess_rank();
278
                if (rank >= 0)
279
                {
×
280
#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 110000
281
#pragma GCC diagnostic push
282
#pragma GCC diagnostic ignored "-Wrestrict"
×
283
#endif
284
                    std::string const temp =
285
                        "(" + std::to_string(guess_rank()) + ")";
×
286
#if defined(HPX_GCC_VERSION) && HPX_GCC_VERSION >= 110000
287
#pragma GCC diagnostic pop
288
#endif
289
                    std::strcat(hostname_, temp.c_str());
290
                }
×
291
            }
292
            return hostname_;
293
        }
×
294

×
295
        [[nodiscard]] int hostname_print_helper::guess_rank() const
296
        {
×
297
#if defined(__FreeBSD__)
×
298
            char** env = freebsd_environ;
299
#else
300
            char** env = environ;
×
301
#endif
302
            std::vector<std::string> const env_strings{//-V826
×
303
                "_RANK=", "_NODEID="};
304
            for (char** current = env; *current; ++current)
305
            {
306
                auto e = std::string(*current);
307
                for (auto const& s : env_strings)
×
308
                {
309
                    auto const pos = e.find(s);
×
310
                    if (pos != std::string::npos)
311
                    {
×
312
                        return std::stoi(e.substr(pos + s.size(), 5));
×
313
                    }
314
                }
315
            }
316
            return -1;
317
        }
×
318

319
        std::ostream& operator<<(std::ostream& os, hostname_print_helper h)
320
        {
321
            os << debug::str<13>(h.get_hostname()) << " ";
×
322
            return os;
×
323
        }
×
324

×
325
        ///////////////////////////////////////////////////////////////////////
×
326
        template <typename T>
327
        HPX_CORE_EXPORT void print_array(
328
            std::string const& name, T const* data, std::size_t size)
329
        {
330
            std::cout << str<20>(name.c_str()) << ": {" << debug::dec<4>(size)
331
                      << "} : ";
332
            std::copy(
333
                data, data + size, std::ostream_iterator<T>(std::cout, ", "));
334
            std::cout << "\n";
335
        }
336

337
        template HPX_CORE_EXPORT void print_array(
338
            std::string const&, std::uint64_t const*, std::size_t);
339
    }    // namespace detail
340
}    // namespace hpx::debug
341
/// \endcond
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

© 2025 Coveralls, Inc