Skip to content

Commit d5b5885

Browse files
committed
Disable GDBRegistrationListener
It makes emitting object extremely slow. GDB doesn't work properly with it anyway. GDB also often crashes because it cannot read the format.
1 parent 6516f56 commit d5b5885

File tree

1 file changed

+1
-171
lines changed

1 file changed

+1
-171
lines changed

‎lib/ExecutionEngine/GDBRegistrationListener.cpp‎

Lines changed: 1 addition & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -19,84 +19,16 @@
1919
using namespace llvm;
2020
using namespace llvm::object;
2121

22-
// This must be kept in sync with gdb/gdb/jit.h .
23-
extern "C" {
24-
25-
typedef enum {
26-
JIT_NOACTION = 0,
27-
JIT_REGISTER_FN,
28-
JIT_UNREGISTER_FN
29-
} jit_actions_t;
30-
31-
struct jit_code_entry {
32-
struct jit_code_entry *next_entry;
33-
struct jit_code_entry *prev_entry;
34-
const char *symfile_addr;
35-
uint64_t symfile_size;
36-
};
37-
38-
struct jit_descriptor {
39-
uint32_t version;
40-
// This should be jit_actions_t, but we want to be specific about the
41-
// bit-width.
42-
uint32_t action_flag;
43-
struct jit_code_entry *relevant_entry;
44-
struct jit_code_entry *first_entry;
45-
};
46-
47-
// We put information about the JITed function in this global, which the
48-
// debugger reads. Make sure to specify the version statically, because the
49-
// debugger checks the version before we can set it during runtime.
50-
extern struct jit_descriptor __jit_debug_descriptor;
51-
52-
// Debuggers puts a breakpoint in this function.
53-
extern "C" void __jit_debug_register_code();
54-
}
55-
5622
namespace {
5723

58-
// FIXME: lli aims to provide both, RuntimeDyld and JITLink, as the dynamic
59-
// loaders for it's JIT implementations. And they both offer debugging via the
60-
// GDB JIT interface, which builds on the two well-known symbol names below.
61-
// As these symbols must be unique accross the linked executable, we can only
62-
// define them in one of the libraries and make the other depend on it.
63-
// OrcTargetProcess is a minimal stub for embedding a JIT client in remote
64-
// executors. For the moment it seems reasonable to have the definition there
65-
// and let ExecutionEngine depend on it, until we find a better solution.
66-
//
67-
LLVM_ATTRIBUTE_USED void requiredSymbolDefinitionsFromOrcTargetProcess() {
68-
errs() << (void *)&__jit_debug_register_code
69-
<< (void *)&__jit_debug_descriptor;
70-
}
71-
72-
struct RegisteredObjectInfo {
73-
RegisteredObjectInfo() {}
74-
75-
RegisteredObjectInfo(std::size_t Size, jit_code_entry *Entry,
76-
OwningBinary<ObjectFile> Obj)
77-
: Size(Size), Entry(Entry), Obj(std::move(Obj)) {}
78-
79-
std::size_t Size;
80-
jit_code_entry *Entry;
81-
OwningBinary<ObjectFile> Obj;
82-
};
83-
84-
// Buffer for an in-memory object file in executable memory
85-
typedef llvm::DenseMap<JITEventListener::ObjectKey, RegisteredObjectInfo>
86-
RegisteredObjectBufferMap;
87-
8824
/// Global access point for the JIT debugging interface designed for use with a
8925
/// singleton toolbox. Handles thread-safe registration and deregistration of
9026
/// object files that are in executable memory managed by the client of this
9127
/// class.
9228
class GDBJITRegistrationListener : public JITEventListener {
93-
/// A map of in-memory object files that have been registered with the
94-
/// JIT interface.
95-
RegisteredObjectBufferMap ObjectBufferMap;
96-
9729
public:
9830
/// Instantiates the JIT service.
99-
GDBJITRegistrationListener() : ObjectBufferMap() {}
31+
GDBJITRegistrationListener() {}
10032

10133
/// Unregisters each object that was previously registered and releases all
10234
/// internal resources.
@@ -112,119 +44,17 @@ class GDBJITRegistrationListener : public JITEventListener {
11244
/// frees associated resources.
11345
/// Returns true if @p Object was found in ObjectBufferMap.
11446
void notifyFreeingObject(ObjectKey K) override;
115-
116-
private:
117-
/// Deregister the debug info for the given object file from the debugger
118-
/// and delete any temporary copies. This private method does not remove
119-
/// the function from Map so that it can be called while iterating over Map.
120-
void deregisterObjectInternal(RegisteredObjectBufferMap::iterator I);
12147
};
12248

123-
/// Lock used to serialize all jit registration events, since they
124-
/// modify global variables.
125-
ManagedStatic<sys::Mutex> JITDebugLock;
126-
127-
/// Do the registration.
128-
void NotifyDebugger(jit_code_entry* JITCodeEntry) {
129-
__jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
130-
131-
// Insert this entry at the head of the list.
132-
JITCodeEntry->prev_entry = nullptr;
133-
jit_code_entry* NextEntry = __jit_debug_descriptor.first_entry;
134-
JITCodeEntry->next_entry = NextEntry;
135-
if (NextEntry) {
136-
NextEntry->prev_entry = JITCodeEntry;
137-
}
138-
__jit_debug_descriptor.first_entry = JITCodeEntry;
139-
__jit_debug_descriptor.relevant_entry = JITCodeEntry;
140-
__jit_debug_register_code();
141-
}
142-
14349
GDBJITRegistrationListener::~GDBJITRegistrationListener() {
144-
// Free all registered object files.
145-
std::lock_guard<llvm::sys::Mutex> locked(*JITDebugLock);
146-
for (RegisteredObjectBufferMap::iterator I = ObjectBufferMap.begin(),
147-
E = ObjectBufferMap.end();
148-
I != E; ++I) {
149-
// Call the private method that doesn't update the map so our iterator
150-
// doesn't break.
151-
deregisterObjectInternal(I);
152-
}
153-
ObjectBufferMap.clear();
15450
}
15551

15652
void GDBJITRegistrationListener::notifyObjectLoaded(
15753
ObjectKey K, const ObjectFile &Obj,
15854
const RuntimeDyld::LoadedObjectInfo &L) {
159-
160-
OwningBinary<ObjectFile> DebugObj = L.getObjectForDebug(Obj);
161-
162-
// Bail out if debug objects aren't supported.
163-
if (!DebugObj.getBinary())
164-
return;
165-
166-
const char *Buffer = DebugObj.getBinary()->getMemoryBufferRef().getBufferStart();
167-
size_t Size = DebugObj.getBinary()->getMemoryBufferRef().getBufferSize();
168-
169-
std::lock_guard<llvm::sys::Mutex> locked(*JITDebugLock);
170-
assert(ObjectBufferMap.find(K) == ObjectBufferMap.end() &&
171-
"Second attempt to perform debug registration.");
172-
jit_code_entry* JITCodeEntry = new jit_code_entry();
173-
174-
if (!JITCodeEntry) {
175-
llvm::report_fatal_error(
176-
"Allocation failed when registering a JIT entry!\n");
177-
} else {
178-
JITCodeEntry->symfile_addr = Buffer;
179-
JITCodeEntry->symfile_size = Size;
180-
181-
ObjectBufferMap[K] =
182-
RegisteredObjectInfo(Size, JITCodeEntry, std::move(DebugObj));
183-
NotifyDebugger(JITCodeEntry);
184-
}
18555
}
18656

18757
void GDBJITRegistrationListener::notifyFreeingObject(ObjectKey K) {
188-
std::lock_guard<llvm::sys::Mutex> locked(*JITDebugLock);
189-
RegisteredObjectBufferMap::iterator I = ObjectBufferMap.find(K);
190-
191-
if (I != ObjectBufferMap.end()) {
192-
deregisterObjectInternal(I);
193-
ObjectBufferMap.erase(I);
194-
}
195-
}
196-
197-
void GDBJITRegistrationListener::deregisterObjectInternal(
198-
RegisteredObjectBufferMap::iterator I) {
199-
200-
jit_code_entry*& JITCodeEntry = I->second.Entry;
201-
202-
// Do the unregistration.
203-
{
204-
__jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;
205-
206-
// Remove the jit_code_entry from the linked list.
207-
jit_code_entry* PrevEntry = JITCodeEntry->prev_entry;
208-
jit_code_entry* NextEntry = JITCodeEntry->next_entry;
209-
210-
if (NextEntry) {
211-
NextEntry->prev_entry = PrevEntry;
212-
}
213-
if (PrevEntry) {
214-
PrevEntry->next_entry = NextEntry;
215-
}
216-
else {
217-
assert(__jit_debug_descriptor.first_entry == JITCodeEntry);
218-
__jit_debug_descriptor.first_entry = NextEntry;
219-
}
220-
221-
// Tell the debugger which entry we removed, and unregister the code.
222-
__jit_debug_descriptor.relevant_entry = JITCodeEntry;
223-
__jit_debug_register_code();
224-
}
225-
226-
delete JITCodeEntry;
227-
JITCodeEntry = nullptr;
22858
}
22959

23060
llvm::ManagedStatic<GDBJITRegistrationListener> GDBRegListener;

0 commit comments

Comments
 (0)