diff --git a/.bazelrc b/.bazelrc index f3d406b0..da245813 100644 --- a/.bazelrc +++ b/.bazelrc @@ -17,7 +17,7 @@ # Default build options. These are applied first and unconditionally. # -build --cxxopt="-std=c++11" +build --cxxopt="-std=c++17" # Use gnu11 for asm keyword. build --conlyopt="-std=gnu11" diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index 09f0d3cb..722d633f 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -10,14 +10,18 @@ on: paths-ignore: - '**.md' +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + env: proc_num: $(nproc) jobs: gcc-compile-with-make: - runs-on: ubuntu-20.04 # https://github.com/actions/runner-images + runs-on: ubuntu-24.04 # https://github.com/actions/runner-images steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v7 - uses: ./.github/actions/install-essential-dependences - uses: ./.github/actions/init-make-config with: @@ -27,9 +31,9 @@ jobs: make -j ${{env.proc_num}} gcc-compile-with-cmake: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v7 - uses: ./.github/actions/install-essential-dependences - name: cmake run: | @@ -43,9 +47,9 @@ jobs: make -j ${{env.proc_num}} gcc-compile-with-bazel: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v7 - name: install dependences run: | sudo apt-get update @@ -56,9 +60,9 @@ jobs: bazel build -j ${{env.proc_num}} -c opt --copt -DHAVE_ZLIB=1 //... gcc-compile-with-make-all-options: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v7 - uses: ./.github/actions/install-all-dependences - uses: ./.github/actions/init-make-config with: @@ -68,9 +72,9 @@ jobs: make -j ${{env.proc_num}} gcc-compile-with-cmake-all-options: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v7 - uses: ./.github/actions/install-all-dependences - name: cmake run: | @@ -84,9 +88,9 @@ jobs: make -j ${{env.proc_num}} gcc-compile-with-bazel-all-options: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v7 - name: install dependences run: | sudo apt-get update @@ -96,100 +100,18 @@ jobs: export CC=gcc && export CXX=g++ bazel build -j 12 -c opt --define with_mesalink=false --define with_glog=true --define with_thrift=true --copt -DHAVE_ZLIB=1 //... - - clang-compile-with-make: - runs-on: ubuntu-20.04 + gcc-unittest: + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v7 - uses: ./.github/actions/install-essential-dependences - - uses: ./.github/actions/init-make-config - with: - options: --cc=clang --cxx=clang++ - - name: compile - run: | - make -j ${{env.proc_num}} - - clang-compile-with-cmake: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-essential-dependences - - name: cmake - run: | - export CC=clang && export CXX=clang++ - mkdir build - cd build - cmake .. - - name: compile - run: | - cd build - make -j ${{env.proc_num}} - - clang-compile-with-bazel: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - name: install dependences + - name: install test dependencies run: | sudo apt-get update - sudo apt-get install libibverbs-dev - - name: compile - run: | - export CC=clang && export CXX=clang++ - bazel build -j ${{env.proc_num}} -c opt --copt -DHAVE_ZLIB=1 //... - - clang-compile-with-make-all-options: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-all-dependences + sudo apt-get install -y gdb libgtest-dev - uses: ./.github/actions/init-make-config with: - options: --cc=clang --cxx=clang++ --with-thrift --with-glog - - name: compile - run: | - make -j ${{env.proc_num}} - - clang-compile-with-cmake-all-options: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-all-dependences - - name: cmake - run: | - export CC=clang && export CXX=clang++ - mkdir build - cd build - cmake -DWITH_MESALINK=OFF -DWITH_GLOG=ON -DWITH_THRIFT=ON .. - - name: compile - run: | - cd build - make -j ${{env.proc_num}} - - clang-compile-with-bazel-all-options: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - name: install dependences - run: | - sudo apt-get update - sudo apt-get install libibverbs-dev - - name: compile - run: | - export CC=clang && export CXX=clang++ - bazel build -j ${{env.proc_num}} -c opt --define with_mesalink=false --define with_glog=true --define with_thrift=true --copt -DHAVE_ZLIB=1 //... - - clang-unittest: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - uses: ./.github/actions/install-essential-dependences - - name: install gtest - run: | - sudo apt-get install -y cmake libgtest-dev && cd /usr/src/gtest && sudo cmake . && sudo make && sudo mv lib/libgtest* /usr/lib/ - - uses: ./.github/actions/init-make-config - with: - options: --cc=clang --cxx=clang++ + options: --cc=gcc --cxx=g++ - name: compile tests run: | cd test diff --git a/.github/workflows/ci-macos.yml b/.github/workflows/ci-macos.yml deleted file mode 100644 index 4e98aa31..00000000 --- a/.github/workflows/ci-macos.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Build on Macos - -on: - push: - branches: [ master ] - paths-ignore: - - '**.md' - pull_request: - branches: [ master ] - paths-ignore: - - '**.md' - -env: - proc_num: $(sysctl -n hw.logicalcpu) - -jobs: - compile-with-make: - runs-on: macos-latest # https://github.com/actions/runner-images - - steps: - - uses: actions/checkout@v2 - - - name: install dependences - run: | - brew install ./homebrew-formula/protobuf.rb - brew install openssl gnu-getopt coreutils gflags leveldb - - - name: config_brpc - run: | - GETOPT_PATH=$(find "/usr/local/Cellar/" -name "getopt" -type f -perm +111 -exec dirname {} \;) - export PATH=$GETOPT_PATH:$PATH - ./config_brpc.sh --header="/usr/local/include" --libs="/usr/local/lib" - - - name: compile - run: | - make -j ${{env.proc_num}} - - compile-with-cmake: - runs-on: macos-latest - - steps: - - uses: actions/checkout@v2 - - - name: install dependences - run: | - brew install ./homebrew-formula/protobuf.rb - brew install openssl gnu-getopt coreutils gflags leveldb - - - name: cmake - run: | - mkdir build - cd build - cmake .. - - - name: compile - run: | - cd build - make -j ${{env.proc_num}} diff --git a/.github/workflows/license-eyes.yml b/.github/workflows/license-eyes.yml index 9ae09778..f408dbaf 100644 --- a/.github/workflows/license-eyes.yml +++ b/.github/workflows/license-eyes.yml @@ -22,13 +22,18 @@ on: push: branches: - master + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: license-check: name: "License Check" runs-on: ubuntu-latest steps: - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )" - uses: actions/checkout@v2 + uses: actions/checkout@v7 - name: Check License uses: apache/skywalking-eyes@v0.4.0 env: diff --git a/WORKSPACE b/WORKSPACE index b6fda836..b67faa72 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -130,7 +130,7 @@ http_archive( sha256 = "5347464af5b14ac54bb945dc68f1dd7c56f0dad7262816b956138fc53bcc0131", strip_prefix = "boost_1_77_0", urls = [ - "https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.tar.gz", + "https://archives.boost.io/release/1.77.0/source/boost_1_77_0.tar.gz", ], ) diff --git a/src/butil/fast_rand.cpp b/src/butil/fast_rand.cpp index 36e0e831..cef45854 100644 --- a/src/butil/fast_rand.cpp +++ b/src/butil/fast_rand.cpp @@ -23,6 +23,7 @@ #include "butil/macros.h" #include "butil/time.h" // gettimeofday_us() #include "butil/fast_rand.h" +#include "butil/numerics/safe_conversions.h" // safe_abs namespace butil { @@ -110,20 +111,31 @@ int64_t fast_rand_in_64(int64_t min, int64_t max) { if (need_init(_tls_seed)) { init_fast_rand_seed(&_tls_seed); } - if (min >= max) { + if (BAIDU_UNLIKELY(min >= max)) { if (min == max) { return min; } - const int64_t tmp = min; - min = max; - max = tmp; + std::swap(min, max); + } + uint64_t range; + if (min >= 0) { + // Always safe to do subtraction. + range = (uint64_t)(max - min) + 1; + return min + (int64_t)fast_rand_impl(range, &_tls_seed); + } + + uint64_t abs_min = safe_abs(min); + if (max >= 0) { + range = abs_min + (uint64_t)(max) + 1; + } else { + range = abs_min - safe_abs(max) + 1; } - int64_t range = max - min + 1; if (range == 0) { // max = INT64_MAX, min = INT64_MIN return (int64_t)xorshift128_next(&_tls_seed); } - return min + (int64_t)fast_rand_impl(max - min + 1, &_tls_seed); + uint64_t r = fast_rand_impl(range, &_tls_seed); + return r >= abs_min ? (int64_t)(r - abs_min) : -((int64_t)(abs_min - r)); } uint64_t fast_rand_in_u64(uint64_t min, uint64_t max) { diff --git a/src/butil/numerics/safe_conversions.h b/src/butil/numerics/safe_conversions.h index 677aa4af..9a488117 100644 --- a/src/butil/numerics/safe_conversions.h +++ b/src/butil/numerics/safe_conversions.h @@ -58,6 +58,31 @@ inline Dst saturated_cast(Src value) { return static_cast(value); } +inline uint64_t safe_abs(uint64_t x) { + return x; +} + +inline uint64_t safe_abs(int64_t x) { + return (x >= 0) ? (uint64_t)x : ((~(uint64_t)(x)) + 1); +} + +inline uint32_t safe_abs(uint32_t x) { + return x; +} + +inline uint32_t safe_abs(int32_t x) { + return (uint32_t)safe_abs((int64_t)x); +} + +#if defined(__APPLE__) +inline unsigned long safe_abs(unsigned long x) { + return x; +} +inline unsigned long safe_abs(long x) { + return (x >= 0) ? (unsigned long)x : ((~(unsigned long)(x)) + 1); +} +#endif + } // namespace butil #endif // BUTIL_SAFE_CONVERSIONS_H_ diff --git a/src/butil/strings/string_number_conversions.cc b/src/butil/strings/string_number_conversions.cc index 29645dec..bcf3f49c 100644 --- a/src/butil/strings/string_number_conversions.cc +++ b/src/butil/strings/string_number_conversions.cc @@ -12,6 +12,7 @@ #include #include "butil/logging.h" +#include "butil/numerics/safe_conversions.h" // safe_abs #include "butil/scoped_clear_errno.h" #include "butil/strings/utf_string_conversions.h" #include "butil/third_party/dmg_fp/dmg_fp.h" @@ -22,30 +23,6 @@ namespace { template struct IntToStringT { - // This is to avoid a compiler warning about unary minus on unsigned type. - // For example, say you had the following code: - // template - // INT abs(INT value) { return value < 0 ? -value : value; } - // Even though if INT is unsigned, it's impossible for value < 0, so the - // unary minus will never be taken, the compiler will still generate a - // warning. We do a little specialization dance... - template - struct ToUnsignedT {}; - - template - struct ToUnsignedT { - static UINT2 ToUnsigned(INT2 value) { - return static_cast(value); - } - }; - - template - struct ToUnsignedT { - static UINT2 ToUnsigned(INT2 value) { - return static_cast(value < 0 ? -value : value); - } - }; - // This set of templates is very similar to the above templates, but // for testing whether an integer is negative. template @@ -74,9 +51,7 @@ struct IntToStringT { STR outbuf(kOutputBufSize, 0); bool is_neg = TestNegT::TestNeg(value); - // Even though is_neg will never be true when INT is parameterized as - // unsigned, even the presence of the unary operation causes a warning. - UINT res = ToUnsignedT::ToUnsigned(value); + UINT res = safe_abs(value); typename STR::iterator it(outbuf.end()); do { diff --git a/src/butil/strings/stringprintf.cc b/src/butil/strings/stringprintf.cc index 3f40e724..0ca6366c 100644 --- a/src/butil/strings/stringprintf.cc +++ b/src/butil/strings/stringprintf.cc @@ -78,7 +78,7 @@ static void StringAppendVT(StringType* dst, // wrong and no amount of buffer-doubling is going to fix it. return; #else - if (errno != 0 && errno != EOVERFLOW) + if (errno != 0 && errno != EOVERFLOW && errno != E2BIG) return; // Try doubling the buffer size. mem_length *= 2; diff --git a/test/Makefile b/test/Makefile index bff4b436..70914fca 100644 --- a/test/Makefile +++ b/test/Makefile @@ -201,7 +201,7 @@ FORCE: test_butil:$(TEST_BUTIL_OBJS) | libbrpc.dbg.$(SOEXT) @echo "> Linking $@" ifeq ($(SYSTEM),Linux) - $(CXX) -o $@ $(LIBPATHS) $(SOPATHS) -Xlinker "-(" $^ -Xlinker "-)" $(STATIC_LINKINGS) $(UT_DYNAMIC_LINKINGS) + $(CXX) -no-pie -o $@ $(LIBPATHS) $(SOPATHS) -Xlinker "-(" $^ -Xlinker "-)" $(STATIC_LINKINGS) $(UT_DYNAMIC_LINKINGS) else ifeq ($(SYSTEM),Darwin) $(CXX) -o $@ $(LIBPATHS) $(SOPATHS) $^ $(STATIC_LINKINGS) $(UT_DYNAMIC_LINKINGS) endif diff --git a/test/brpc_naming_service_unittest.cpp b/test/brpc_naming_service_unittest.cpp index 43ac9f47..0ba2be66 100644 --- a/test/brpc_naming_service_unittest.cpp +++ b/test/brpc_naming_service_unittest.cpp @@ -77,33 +77,42 @@ TEST(NamingServiceTest, sanity) { ASSERT_EQ(0, bns.GetServers("qa-pbrpc.SAT.tjyx", &servers)); #endif + auto collect_ips = [&servers]() { + std::set ret; + for (auto& server : servers) { + ret.insert(server.addr.ip); + } + return ret; + }; brpc::policy::DomainNamingService dns; ASSERT_EQ(0, dns.GetServers("baidu.com:1234", &servers)); - ASSERT_EQ(2u, servers.size()); - ASSERT_EQ(1234, servers[0].addr.port); - ASSERT_EQ(1234, servers[1].addr.port); - const std::set expected_ips{servers[0].addr.ip, servers[1].addr.ip}; + size_t server_size = servers.size(); + ASSERT_GE(server_size, 1); + for (size_t i = 0; i < servers.size(); ++i) { + ASSERT_EQ(1234, servers[i].addr.port); + } + const auto expected_ips = collect_ips(); ASSERT_EQ(0, dns.GetServers("baidu.com", &servers)); - ASSERT_EQ(2u, servers.size()); - const std::set ip_list1{servers[0].addr.ip, servers[1].addr.ip}; - ASSERT_TRUE(IsIPListEqual(expected_ips, ip_list1)); - ASSERT_EQ(80, servers[0].addr.port); - ASSERT_EQ(80, servers[1].addr.port); + ASSERT_EQ(server_size, servers.size()); + ASSERT_TRUE(IsIPListEqual(expected_ips, collect_ips())); + for (size_t i = 0; i < servers.size(); ++i) { + ASSERT_EQ(80, servers[i].addr.port); + } ASSERT_EQ(0, dns.GetServers("baidu.com:1234/useless1/useless2", &servers)); - ASSERT_EQ(2u, servers.size()); - const std::set ip_list2{servers[0].addr.ip, servers[1].addr.ip}; - ASSERT_TRUE(IsIPListEqual(expected_ips, ip_list2)); - ASSERT_EQ(1234, servers[0].addr.port); - ASSERT_EQ(1234, servers[1].addr.port); + ASSERT_EQ(server_size, servers.size()); + ASSERT_TRUE(IsIPListEqual(expected_ips, collect_ips())); + for (size_t i = 0; i < servers.size(); ++i) { + ASSERT_EQ(1234, servers[i].addr.port); + } ASSERT_EQ(0, dns.GetServers("baidu.com/useless1/useless2", &servers)); - ASSERT_EQ(2u, servers.size()); - const std::set ip_list3{servers[0].addr.ip, servers[1].addr.ip}; - ASSERT_TRUE(IsIPListEqual(expected_ips, ip_list3)); - ASSERT_EQ(80, servers[0].addr.port); - ASSERT_EQ(80, servers[1].addr.port); + ASSERT_EQ(server_size, servers.size()); + ASSERT_TRUE(IsIPListEqual(expected_ips, collect_ips())); + for (size_t i = 0; i < servers.size(); ++i) { + ASSERT_EQ(80, servers[i].addr.port); + } const char *address_list[] = { "10.127.0.1:1234",