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
17namespace DB
18{
19
20namespace 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.
29class FunctionTrap : public IFunction
30{
31private:
32 const Context & context;
33
34public:
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
142void registerFunctionTrap(FunctionFactory & factory)
143{
144 factory.registerFunction<FunctionTrap>();
145}
146
147}
148
149#else
150
151namespace DB
152{
153 class FunctionFactory;
154 void registerFunctionTrap(FunctionFactory &) {}
155}
156
157#endif
158