ClickHouse

Форк
0
200 строк · 5.9 Кб
1
#if 0
2

3
#include <Functions/IFunction.h>
4
#include <Functions/FunctionFactory.h>
5
#include <Functions/FunctionHelpers.h>
6
#include <DataTypes/DataTypeString.h>
7
#include <DataTypes/DataTypesNumber.h>
8
#include <Columns/ColumnString.h>
9
#include <Interpreters/Context.h>
10
#include <base/scope_guard.h>
11

12
#include <thread>
13
#include <memory>
14
#include <cstdlib>
15
#include <unistd.h>
16
#include <sys/mman.h>
17
#include <dlfcn.h>
18

19

20
namespace DB
21
{
22

23
namespace ErrorCodes
24
{
25
    extern const int ILLEGAL_COLUMN;
26
    extern const int ILLEGAL_TYPE_OF_ARGUMENT;
27
    extern const int BAD_ARGUMENTS;
28
    extern const int CANNOT_ALLOCATE_MEMORY;
29
    extern const int CANNOT_DLOPEN;
30
    extern const int LOGICAL_ERROR;
31
}
32

33

34
/// Various illegal actions to test diagnostic features of ClickHouse itself. Should not be enabled in production builds.
35
class FunctionTrap : public IFunction
36
{
37
private:
38
    ContextPtr context;
39

40
public:
41
    static constexpr auto name = "trap";
42
    static FunctionPtr create(ContextPtr context)
43
    {
44
        return std::make_shared<FunctionTrap>(context);
45
    }
46

47
    FunctionTrap(ContextPtr context_) : context(context_) {}
48

49
    String getName() const override
50
    {
51
        return name;
52
    }
53

54
    size_t getNumberOfArguments() const override
55
    {
56
        return 1;
57
    }
58

59
    bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
60

61
    DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
62
    {
63
        if (!isString(arguments[0]))
64
            throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "The only argument for function {} must be constant String", getName());
65

66
        return std::make_shared<DataTypeUInt8>();
67
    }
68

69
    [[clang::optnone]]
70
    ColumnPtr executeImpl(const ColumnsWithTypeAndName & block, const DataTypePtr & result_type, size_t input_rows_count) const override
71
    {
72
        if (const ColumnConst * column = checkAndGetColumnConst<ColumnString>(block[0].column.get()))
73
        {
74
            String mode = column->getValue<String>();
75

76
            if (mode == "read nullptr c++")
77
            {
78
                volatile int x = *reinterpret_cast<const volatile int *>(0);
79
                (void)x;
80
            }
81
            else if (mode == "read nullptr asm")
82
            {
83
                __asm__ volatile ("movq $0, %rax");
84
                __asm__ volatile ("movq (%rax), %rax");
85
            }
86
            else if (mode == "illegal instruction")
87
            {
88
                __asm__ volatile ("ud2a");
89
            }
90
            else if (mode == "abort")
91
            {
92
                abort();
93
            }
94
            else if (mode == "std::terminate")
95
            {
96
                std::terminate();
97
            }
98
            else if (mode == "use after free")
99
            {
100
                int * x_ptr;
101
                {
102
                    auto x = std::make_unique<int>();
103
                    x_ptr = x.get();
104
                }
105
                *x_ptr = 1;
106
                (void)x_ptr;
107
            }
108
            else if (mode == "use after scope")
109
            {
110
                volatile int * x_ptr;
111
                [&]{
112
                    volatile int x = 0;
113
                    x_ptr = &x;
114
                    (void)x;
115
                }();
116
                [&]{
117
                    volatile int y = 1;
118
                    *x_ptr = 2;
119
                    (void)y;
120
                }();
121
                (void)x_ptr;
122
            }
123
            else if (mode == "uninitialized memory")
124
            {
125
                int x;
126
                (void)write(2, &x, sizeof(x));
127
            }
128
            else if (mode == "data race")
129
            {
130
                int x = 0;
131
                std::thread t1([&]{ ++x; });
132
                std::thread t2([&]{ ++x; });
133
                t1.join();
134
                t2.join();
135
            }
136
            else if (mode == "throw exception")
137
            {
138
                std::vector<int>().at(0);
139
            }
140
            else if (mode == "access context")
141
            {
142
                (void)context->getCurrentQueryId();
143
            }
144
            else if (mode == "stack overflow")
145
            {
146
                executeImpl(block, result_type, input_rows_count);
147
            }
148
            else if (mode == "harmful function")
149
            {
150
                double res = drand48();
151
                (void)res;
152
            }
153
            else if (mode == "mmap many")
154
            {
155
                std::vector<void *> maps;
156
                SCOPE_EXIT(
157
                {
158
                    //for (void * map : maps)
159
                    //    munmap(map, 4096);
160
                });
161

162
                while (true)
163
                {
164
                    void * hint = reinterpret_cast<void *>(
165
                        std::uniform_int_distribution<intptr_t>(0x100000000000UL, 0x700000000000UL)(thread_local_rng));
166
                    void * map = mmap(hint, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
167
                    if (MAP_FAILED == map)
168
                        throw ErrnoException(ErrorCodes::CANNOT_ALLOCATE_MEMORY, "Allocator: Cannot mmap");
169
                    maps.push_back(map);
170
                }
171
            }
172
            else if (mode == "dlopen")
173
            {
174
                void * handle = dlopen("libc.so.6", RTLD_NOW);
175
                if (!handle)
176
                    throw Exception(ErrorCodes::CANNOT_DLOPEN, "Cannot dlopen: ({})", dlerror()); // NOLINT(concurrency-mt-unsafe) // MT-Safe on Linux, see man dlerror
177
            }
178
            else if (mode == "logical error")
179
            {
180
                throw Exception(ErrorCodes::LOGICAL_ERROR, "Trap");
181
            }
182
            else
183
                throw Exception(ErrorCodes::BAD_ARGUMENTS, "Unknown trap mode");
184
        }
185
        else
186
            throw Exception(ErrorCodes::ILLEGAL_COLUMN, "The only argument for function {} must be constant String", getName());
187

188
        return result_type->createColumnConst(input_rows_count, 0ULL);
189
    }
190
};
191

192

193
REGISTER_FUNCTION(Trap)
194
{
195
    factory.registerFunction<FunctionTrap>();
196
}
197

198
}
199

200
#endif
201

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.