未验证 提交 c3bd02e3 编写于 作者: 羽飞's avatar 羽飞 提交者: GitHub

编译选项增加 Werror (#182)

### What problem were solved in this pull request?

Issue Number: close #91 close #1 

Problem:
编译时编译器抛出的一些告警信息可以帮我们避免很多问题,但是现在并没有利用这个特性

### What is changed and how it works?
CMake中增加-Werror编译选项

### Other information
上级 a4fbe1da
...@@ -22,11 +22,6 @@ ...@@ -22,11 +22,6 @@
"label": "build_release", "label": "build_release",
"type": "shell", "type": "shell",
"command": "bash build.sh release" "command": "bash build.sh release"
},
{
"label": "build_release_asan",
"type": "shell",
"command": "bash build.sh release_asan"
} }
] ]
} }
\ No newline at end of file
...@@ -16,7 +16,7 @@ MESSAGE(STATUS "This is PROJECT_BINARY_DIR dir " ${PROJECT_BINARY_DIR}) ...@@ -16,7 +16,7 @@ MESSAGE(STATUS "This is PROJECT_BINARY_DIR dir " ${PROJECT_BINARY_DIR})
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
#SET(LIBRARY_OUTPUT_PATH <路径>) #SET(LIBRARY_OUTPUT_PATH <路径>)
OPTION(ENABLE_ASAN "Enable build with address sanitizer" OFF) OPTION(ENABLE_ASAN "Enable build with address sanitizer" ON)
OPTION(WITH_UNIT_TESTS "Compile miniob with unit tests" ON) OPTION(WITH_UNIT_TESTS "Compile miniob with unit tests" ON)
OPTION(CONCURRENCY "Support concurrency operations" OFF) OPTION(CONCURRENCY "Support concurrency operations" OFF)
...@@ -40,7 +40,7 @@ ELSE() ...@@ -40,7 +40,7 @@ ELSE()
ENDIF(WIN32) ENDIF(WIN32)
# This is for clangd plugin for vscode # This is for clangd plugin for vscode
SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wall -DCMAKE_EXPORT_COMPILE_COMMANDS=1") SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wall -Werror")
IF(DEBUG) IF(DEBUG)
MESSAGE("DEBUG has been set as TRUE ${DEBUG}") MESSAGE("DEBUG has been set as TRUE ${DEBUG}")
SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -O0 -g -DDEBUG ") SET(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -O0 -g -DDEBUG ")
......
...@@ -11,7 +11,6 @@ ALL_ARGS=("$@") ...@@ -11,7 +11,6 @@ ALL_ARGS=("$@")
BUILD_ARGS=() BUILD_ARGS=()
MAKE_ARGS=(-j $CPU_CORES) MAKE_ARGS=(-j $CPU_CORES)
MAKE=make MAKE=make
ASAN_OPTION=ON
echo "$0 ${ALL_ARGS[@]}" echo "$0 ${ALL_ARGS[@]}"
...@@ -24,7 +23,7 @@ function usage ...@@ -24,7 +23,7 @@ function usage
echo "./build.sh [BuildType] [--make [MakeOptions]]" echo "./build.sh [BuildType] [--make [MakeOptions]]"
echo "" echo ""
echo "OPTIONS:" echo "OPTIONS:"
echo "BuildType => debug(default), release, debug_asan, release_asan" echo "BuildType => debug(default), release"
echo "MakeOptions => Options to make command, default: -j N" echo "MakeOptions => Options to make command, default: -j N"
echo "" echo ""
...@@ -137,15 +136,9 @@ function build ...@@ -137,15 +136,9 @@ function build
xrelease) xrelease)
do_build "$@" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEBUG=OFF do_build "$@" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEBUG=OFF
;; ;;
xrelease_asan)
do_build "$@" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DDEBUG=OFF -DENABLE_ASAN=$ASAN_OPTION
;;
xdebug) xdebug)
do_build "$@" -DCMAKE_BUILD_TYPE=Debug -DDEBUG=ON do_build "$@" -DCMAKE_BUILD_TYPE=Debug -DDEBUG=ON
;; ;;
xdebug_asan)
do_build "$@" -DCMAKE_BUILD_TYPE=Debug -DDEBUG=ON -DENABLE_ASAN=$ASAN_OPTION
;;
*) *)
BUILD_ARGS=(debug "${BUILD_ARGS[@]}") BUILD_ARGS=(debug "${BUILD_ARGS[@]}")
build build
......
...@@ -36,6 +36,11 @@ int find_first_setted(char byte, int start) ...@@ -36,6 +36,11 @@ int find_first_setted(char byte, int start)
return -1; return -1;
} }
int bytes(int size)
{
return size % 8 == 0 ? size / 8 : size / 8 + 1;
}
Bitmap::Bitmap() : bitmap_(nullptr), size_(0) Bitmap::Bitmap() : bitmap_(nullptr), size_(0)
{} {}
Bitmap::Bitmap(char *bitmap, int size) : bitmap_(bitmap), size_(size) Bitmap::Bitmap(char *bitmap, int size) : bitmap_(bitmap), size_(size)
...@@ -69,7 +74,7 @@ int Bitmap::next_unsetted_bit(int start) ...@@ -69,7 +74,7 @@ int Bitmap::next_unsetted_bit(int start)
{ {
int ret = -1; int ret = -1;
int start_in_byte = start % 8; int start_in_byte = start % 8;
for (int iter = start / 8, end = (size_ % 8 == 0 ? size_ / 8 : size_ / 8 + 1); iter <= end; iter++) { for (int iter = start / 8, end = bytes(size_); iter < end; iter++) {
char byte = bitmap_[iter]; char byte = bitmap_[iter];
if (byte != -1) { if (byte != -1) {
int index_in_byte = find_first_zero(byte, start_in_byte); int index_in_byte = find_first_zero(byte, start_in_byte);
...@@ -92,7 +97,7 @@ int Bitmap::next_setted_bit(int start) ...@@ -92,7 +97,7 @@ int Bitmap::next_setted_bit(int start)
{ {
int ret = -1; int ret = -1;
int start_in_byte = start % 8; int start_in_byte = start % 8;
for (int iter = start / 8, end = (size_ % 8 == 0 ? size_ / 8 : size_ / 8 + 1); iter <= end; iter++) { for (int iter = start / 8, end = bytes(size_); iter < end; iter++) {
char byte = bitmap_[iter]; char byte = bitmap_[iter];
if (byte != 0x00) { if (byte != 0x00) {
int index_in_byte = find_first_setted(byte, start_in_byte); int index_in_byte = find_first_setted(byte, start_in_byte);
......
...@@ -82,9 +82,20 @@ ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T ...@@ -82,9 +82,20 @@ ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T
return lower_bound<ForwardIterator, T, Comparator<T>>(first, last, val, Comparator<T>(), _found); return lower_bound<ForwardIterator, T, Comparator<T>>(first, last, val, Comparator<T>(), _found);
} }
// std::iterator is deprecated
// refer to https://www.fluentcpp.com/2018/05/08/std-iterator-deprecated/#:~:text=std%3A%3Aiterator%20is%20deprecated%2C%20so%20we%20should%20stop%20using,the%205%20aliases%20inside%20of%20your%20custom%20iterators.
// a sample code:
// https://github.com/google/googletest/commit/25208a60a27c2e634f46327595b281cb67355700
template <typename T, typename Distance = ptrdiff_t> template <typename T, typename Distance = ptrdiff_t>
class BinaryIterator : public std::iterator<std::random_access_iterator_tag, T *, Distance> class BinaryIterator
{ {
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = Distance;
using pointer = value_type *;
using reference = value_type &;
public: public:
BinaryIterator() = default; BinaryIterator() = default;
BinaryIterator(size_t item_num, T *data) : item_num_(item_num), data_(data) BinaryIterator(size_t item_num, T *data) : item_num_(item_num), data_(data)
......
...@@ -182,7 +182,7 @@ extern Log *g_log; ...@@ -182,7 +182,7 @@ extern Log *g_log;
} \ } \
snprintf(prefix, \ snprintf(prefix, \
sizeof(prefix), \ sizeof(prefix), \
"[%s %s %s:%u %s]>>", \ "[%s %s %s:%u %s] >> ", \
sz_head, \ sz_head, \
(common::g_log)->prefix_msg(level), \ (common::g_log)->prefix_msg(level), \
__FILE_NAME__, \ __FILE_NAME__, \
......
...@@ -189,19 +189,21 @@ int list_file(const char *path, const char *filter_pattern, std::vector<std::str ...@@ -189,19 +189,21 @@ int list_file(const char *path, const char *filter_pattern, std::vector<std::str
files.clear(); files.clear();
struct dirent entry; // readdir_r is deprecated in some systems, so we use readdir instead
struct dirent *pentry = NULL; // as readdir is not thread-safe, it is better to use C++ directory
// TODO
struct dirent *pentry;
char tmp_path[PATH_MAX]; char tmp_path[PATH_MAX];
while ((0 == readdir_r(pdir, &entry, &pentry)) && (NULL != pentry)) { while ((pentry = readdir(pdir)) != NULL) {
if ('.' == entry.d_name[0]) // 跳过./..文件和隐藏文件 if ('.' == pentry->d_name[0]) // 跳过./..文件和隐藏文件
continue; continue;
snprintf(tmp_path, sizeof(tmp_path), "%s/%s", path, entry.d_name); snprintf(tmp_path, sizeof(tmp_path), "%s/%s", path, pentry->d_name);
if (is_directory(tmp_path)) if (is_directory(tmp_path))
continue; continue;
if (!filter_pattern || 0 == regexec(&reg, entry.d_name, 0, NULL, 0)) if (!filter_pattern || 0 == regexec(&reg, pentry->d_name, 0, NULL, 0))
files.push_back(entry.d_name); files.push_back(pentry->d_name);
} }
if (filter_pattern) if (filter_pattern)
...@@ -211,4 +213,4 @@ int list_file(const char *path, const char *filter_pattern, std::vector<std::str ...@@ -211,4 +213,4 @@ int list_file(const char *path, const char *filter_pattern, std::vector<std::str
return files.size(); return files.size();
} }
} // namespace common } // namespace common
\ No newline at end of file
...@@ -48,8 +48,7 @@ std::string get_process_name(const char *prog_name) ...@@ -48,8 +48,7 @@ std::string get_process_name(const char *prog_name)
std::cerr << "Failed to alloc memory for program name." << SYS_OUTPUT_FILE_POS << SYS_OUTPUT_ERROR << std::endl; std::cerr << "Failed to alloc memory for program name." << SYS_OUTPUT_FILE_POS << SYS_OUTPUT_ERROR << std::endl;
return ""; return "";
} }
memset(buf, 0, buf_len + 1); snprintf(buf, buf_len, "%s", prog_name);
strncpy(buf, prog_name, buf_len);
process_name = basename(buf); process_name = basename(buf);
...@@ -158,4 +157,4 @@ void sys_log_redirect(const char *std_out_file, const char *std_err_file) ...@@ -158,4 +157,4 @@ void sys_log_redirect(const char *std_out_file, const char *std_err_file)
return; return;
} }
} // namespace common } // namespace common
\ No newline at end of file
...@@ -73,9 +73,7 @@ void *waitForSignals(void *args) ...@@ -73,9 +73,7 @@ void *waitForSignals(void *args)
int ret = sigwait(signal_set, &sig_number); int ret = sigwait(signal_set, &sig_number);
LOG_INFO("sigwait return value: %d, %d \n", ret, sig_number); LOG_INFO("sigwait return value: %d, %d \n", ret, sig_number);
if (ret != 0) { if (ret != 0) {
char errstr[256]; LOG_ERROR("error (%d) %s\n", errno, strerror(errno));
strerror_r(errno, errstr, sizeof(errstr));
LOG_ERROR("error (%d) %s\n", errno, errstr);
} }
} }
return NULL; return NULL;
...@@ -92,4 +90,4 @@ void startWaitForSignals(sigset_t *signal_set) ...@@ -92,4 +90,4 @@ void startWaitForSignals(sigset_t *signal_set)
pthread_create(&pThread, &pThreadAttrs, waitForSignals, (void *)signal_set); pthread_create(&pThread, &pThreadAttrs, waitForSignals, (void *)signal_set);
} }
} // namespace common } // namespace common
\ No newline at end of file
...@@ -223,13 +223,15 @@ RC CLogBuffer::flush_buffer(CLogFile *log_file) ...@@ -223,13 +223,15 @@ RC CLogBuffer::flush_buffer(CLogFile *log_file)
{ {
if (write_offset_ == CLOG_BUFFER_SIZE) { // 如果是buffer满触发的下刷 if (write_offset_ == CLOG_BUFFER_SIZE) { // 如果是buffer满触发的下刷
CLogBlock *log_block = (CLogBlock *)buffer_; CLogBlock *log_block = (CLogBlock *)buffer_;
log_file->write(log_block->log_block_hdr_.log_block_no, CLOG_BUFFER_SIZE, buffer_); RC rc = log_file->write(log_block->log_block_hdr_.log_block_no, CLOG_BUFFER_SIZE, buffer_);
ASSERT(rc == RC::SUCCESS, "failed to write buffer block to file. error=%s", strerror(errno));
write_block_offset_ = 0; write_block_offset_ = 0;
write_offset_ = 0; write_offset_ = 0;
memset(buffer_, 0, CLOG_BUFFER_SIZE); memset(buffer_, 0, CLOG_BUFFER_SIZE);
} else { } else {
CLogBlock *log_block = (CLogBlock *)buffer_; CLogBlock *log_block = (CLogBlock *)buffer_;
log_file->write(log_block->log_block_hdr_.log_block_no, write_block_offset_ + CLOG_BLOCK_SIZE, buffer_); RC rc = log_file->write(log_block->log_block_hdr_.log_block_no, write_block_offset_ + CLOG_BLOCK_SIZE, buffer_);
ASSERT(rc == RC::SUCCESS, "failed to write buffer block to file. error=%s", strerror(errno));
log_block = (CLogBlock *)&buffer_[write_block_offset_]; log_block = (CLogBlock *)&buffer_[write_block_offset_];
if (log_block->log_block_hdr_.log_data_len_ == CLOG_BLOCK_DATA_SIZE) { // 最后一个block已写满 if (log_block->log_block_hdr_.log_data_len_ == CLOG_BLOCK_DATA_SIZE) { // 最后一个block已写满
write_block_offset_ = 0; write_block_offset_ = 0;
...@@ -397,6 +399,14 @@ void CLogMTRManager::log_record_manage(CLogRecord *log_rec) ...@@ -397,6 +399,14 @@ void CLogMTRManager::log_record_manage(CLogRecord *log_rec)
} }
} }
CLogMTRManager::~CLogMTRManager()
{
for (auto log_rec: log_redo_list) {
delete log_rec;
}
log_redo_list.clear();
}
//////////////////// ////////////////////
std::atomic<int32_t> CLogManager::gloabl_lsn_(0); std::atomic<int32_t> CLogManager::gloabl_lsn_(0);
CLogManager::CLogManager(const char *path) CLogManager::CLogManager(const char *path)
...@@ -410,6 +420,17 @@ CLogManager::~CLogManager() ...@@ -410,6 +420,17 @@ CLogManager::~CLogManager()
{ {
if (log_buffer_) { if (log_buffer_) {
delete log_buffer_; delete log_buffer_;
log_buffer_ = nullptr;
}
if (log_file_ != nullptr) {
delete log_file_;
log_file_ = nullptr;
}
if (log_mtr_mgr_ != nullptr) {
delete log_mtr_mgr_;
log_mtr_mgr_ = nullptr;
} }
} }
......
...@@ -227,6 +227,8 @@ struct CLogMTRManager { ...@@ -227,6 +227,8 @@ struct CLogMTRManager {
std::unordered_map<int32_t, bool> trx_commited; // <trx_id, commited> std::unordered_map<int32_t, bool> trx_commited; // <trx_id, commited>
void log_record_manage(CLogRecord *log_rec); void log_record_manage(CLogRecord *log_rec);
~CLogMTRManager();
}; };
// //
......
...@@ -269,12 +269,14 @@ RC PersistHandler::read_at(uint64_t offset, int size, char *data, int64_t *out_s ...@@ -269,12 +269,14 @@ RC PersistHandler::read_at(uint64_t offset, int size, char *data, int64_t *out_s
strerror(errno)); strerror(errno));
return RC::FILE_SEEK; return RC::FILE_SEEK;
} else { } else {
int64_t read_size = 0; ssize_t read_size = read(file_desc_, data, size);
if ((read_size = read(file_desc_, data, size)) != size) { if (read_size == 0) {
LOG_WARN("Failed to read %lld of %d:%s due to %s.", offset, file_desc_, file_name_.c_str(), strerror(errno)); LOG_TRACE("read file touch the end. file name=%s", file_name_.c_str());
} else if (read_size < 0) {
LOG_WARN("failed to read file. file name=%s, offset=%lld, size=%d, error=%s", file_name_.c_str(), offset, size,
strerror(errno));
rc = RC::FILE_READ; rc = RC::FILE_READ;
} } else if (out_size != nullptr) {
if (out_size != nullptr) {
*out_size = read_size; *out_size = read_size;
} }
} }
......
...@@ -39,6 +39,9 @@ Record *gen_del_record(int32_t page_num, int32_t slot_num) ...@@ -39,6 +39,9 @@ Record *gen_del_record(int32_t page_num, int32_t slot_num)
TEST(test_clog, test_clog) TEST(test_clog, test_clog)
{ {
const char *clog_file = "./clog";
remove(clog_file);
CLogManager *log_mgr = new CLogManager("./"); CLogManager *log_mgr = new CLogManager("./");
CLogRecord *log_rec[6]; CLogRecord *log_rec[6];
...@@ -116,6 +119,7 @@ TEST(test_clog, test_clog) ...@@ -116,6 +119,7 @@ TEST(test_clog, test_clog)
i++; i++;
} }
*/ */
delete log_mgr;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
...@@ -123,7 +127,7 @@ int main(int argc, char **argv) ...@@ -123,7 +127,7 @@ int main(int argc, char **argv)
// 分析gtest程序的命令行参数 // 分析gtest程序的命令行参数
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
LoggerFactory::init_default("test.log", LOG_LEVEL_TRACE); LoggerFactory::init_default("clog_test.log", LOG_LEVEL_TRACE);
// 调用RUN_ALL_TESTS()运行所有测试用例 // 调用RUN_ALL_TESTS()运行所有测试用例
// main函数返回RUN_ALL_TESTS()的运行结果 // main函数返回RUN_ALL_TESTS()的运行结果
......
/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Longda on 2021
//
int main(int argc, char **argv)
{
return 0;
}
\ No newline at end of file
...@@ -104,7 +104,9 @@ TEST(test_record_page_handler, test_record_page_handler) ...@@ -104,7 +104,9 @@ TEST(test_record_page_handler, test_record_page_handler)
} }
ASSERT_EQ(count, 6); ASSERT_EQ(count, 6);
record_page_handle.cleanup();
bpm->close_file(record_manager_file); bpm->close_file(record_manager_file);
delete bpm;
} }
TEST(test_record_page_handler, test_record_file_iterator) TEST(test_record_page_handler, test_record_file_iterator)
...@@ -179,6 +181,7 @@ TEST(test_record_page_handler, test_record_file_iterator) ...@@ -179,6 +181,7 @@ TEST(test_record_page_handler, test_record_file_iterator)
ASSERT_EQ(count, rids.size() / 2); ASSERT_EQ(count, rids.size() / 2);
bpm->close_file(record_manager_file); bpm->close_file(record_manager_file);
delete bpm;
} }
int main(int argc, char **argv) int main(int argc, char **argv)
......
/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved.
miniob is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
//
// Created by Longda on 2021
//
#pragma once
#include "common/lang/mutex.h"
/*
*
*/
class ThreadTest {
public:
ThreadTest();
virtual ~ThreadTest();
int create();
int startTestCond();
int startTestDeadLock();
static void *testCond(void *param);
static void *testDeadLock(void *param);
private:
int param[10];
pthread_mutex_t mutex;
pthread_cond_t cond;
pthread_mutex_t dead_mutex1;
pthread_mutex_t dead_mutex2;
};
#endif /* CTESTTHREAD_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册