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 | |
11 | #include <thread> |
12 | #include <memory> |
13 | #include <cstdlib> |
14 | #include <unistd.h> |
15 | |
16 | |
17 | namespace DB |
18 | { |
19 | |
20 | namespace ErrorCodes |
21 | { |
22 | extern const int ILLEGAL_COLUMN; |
23 | extern const int ILLEGAL_TYPE_OF_ARGUMENT; |
24 | extern const int BAD_ARGUMENTS; |
25 | } |
26 | |
27 | |
28 | /// Various illegal actions to test diagnostic features of ClickHouse itself. Should not be enabled in production builds. |
29 | class FunctionTrap : public IFunction |
30 | { |
31 | private: |
32 | const Context & context; |
33 | |
34 | public: |
35 | static constexpr auto name = "trap" ; |
36 | static FunctionPtr create(const Context & context) |
37 | { |
38 | return std::make_shared<FunctionTrap>(context); |
39 | } |
40 | |
41 | FunctionTrap(const Context & context_) : context(context_) {} |
42 | |
43 | String getName() const override |
44 | { |
45 | return name; |
46 | } |
47 | |
48 | size_t getNumberOfArguments() const override |
49 | { |
50 | return 1; |
51 | } |
52 | |
53 | DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override |
54 | { |
55 | if (!isString(arguments[0])) |
56 | throw Exception("The only argument for function " + getName() + " must be constant String" , ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); |
57 | |
58 | return std::make_shared<DataTypeUInt8>(); |
59 | } |
60 | |
61 | void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override |
62 | { |
63 | if (const ColumnConst * column = checkAndGetColumnConst<ColumnString>(block.getByPosition(arguments[0]).column.get())) |
64 | { |
65 | String mode = column->getValue<String>(); |
66 | |
67 | if (mode == "read nullptr c++" ) |
68 | { |
69 | volatile int x = *reinterpret_cast<const volatile int *>(0); |
70 | (void)x; |
71 | } |
72 | else if (mode == "read nullptr asm" ) |
73 | { |
74 | __asm__ volatile ("movq $0, %rax" ); |
75 | __asm__ volatile ("movq (%rax), %rax" ); |
76 | } |
77 | else if (mode == "illegal instruction" ) |
78 | { |
79 | __asm__ volatile ("ud2a" ); |
80 | } |
81 | else if (mode == "abort" ) |
82 | { |
83 | abort(); |
84 | } |
85 | else if (mode == "std::terminate" ) |
86 | { |
87 | std::terminate(); |
88 | } |
89 | else if (mode == "use after free" ) |
90 | { |
91 | int * x_ptr; |
92 | { |
93 | auto x = std::make_unique<int>(); |
94 | x_ptr = x.get(); |
95 | } |
96 | *x_ptr = 1; |
97 | (void)x_ptr; |
98 | } |
99 | else if (mode == "use after scope" ) |
100 | { |
101 | volatile int * x_ptr; |
102 | [&]{ |
103 | volatile int x = 0; |
104 | x_ptr = &x; |
105 | (void)x; |
106 | }(); |
107 | [&]{ |
108 | volatile int y = 1; |
109 | *x_ptr = 2; |
110 | (void)y; |
111 | }(); |
112 | (void)x_ptr; |
113 | } |
114 | else if (mode == "uninitialized memory" ) |
115 | { |
116 | int x; |
117 | (void)write(2, &x, sizeof(x)); |
118 | } |
119 | else if (mode == "data race" ) |
120 | { |
121 | int x = 0; |
122 | std::thread t1([&]{ ++x; }); |
123 | std::thread t2([&]{ ++x; }); |
124 | t1.join(); |
125 | t2.join(); |
126 | } |
127 | else if (mode == "access context" ) |
128 | { |
129 | (void)context.getCurrentQueryId(); |
130 | } |
131 | else |
132 | throw Exception("Unknown trap mode" , ErrorCodes::BAD_ARGUMENTS); |
133 | } |
134 | else |
135 | throw Exception("The only argument for function " + getName() + " must be constant String" , ErrorCodes::ILLEGAL_COLUMN); |
136 | |
137 | block.getByPosition(result).column = block.getByPosition(result).type->createColumnConst(input_rows_count, 0ULL); |
138 | } |
139 | }; |
140 | |
141 | |
142 | void registerFunctionTrap(FunctionFactory & factory) |
143 | { |
144 | factory.registerFunction<FunctionTrap>(); |
145 | } |
146 | |
147 | } |
148 | |
149 | #else |
150 | |
151 | namespace DB |
152 | { |
153 | class FunctionFactory; |
154 | void registerFunctionTrap(FunctionFactory &) {} |
155 | } |
156 | |
157 | #endif |
158 | |