Skip to content

Commit e628919

Browse files
committed
Only function and file names and limited num frames
1 parent 210f308 commit e628919

File tree

2 files changed

+17
-31
lines changed

2 files changed

+17
-31
lines changed

ext/libdatadog_api/crashtracker.c

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -175,19 +175,13 @@ static VALUE _native_stop(DDTRACE_UNUSED VALUE _self) {
175175
return Qtrue;
176176
}
177177

178-
// Ruby runtime stack callback implementation
179-
// This function will be called by libdatadog during crash handling
178+
180179
static void ruby_runtime_stack_callback(
181180
void (*emit_frame)(const ddog_crasht_RuntimeStackFrame*),
182181
void (*emit_stacktrace_string)(const char*)
183182
) {
184-
// Only using emit_frame - ignore emit_stacktrace_string parameter
185183
(void)emit_stacktrace_string;
186184

187-
// Try to safely walk Ruby stack using direct VM structure access
188-
// Avoid Ruby API calls that might hang in crash context
189-
190-
// First emit a marker frame to show callback is working
191185
ddog_crasht_RuntimeStackFrame marker_frame = {
192186
.function_name = "ruby_stack_walker_start",
193187
.file_name = "crashtracker.c",
@@ -196,7 +190,6 @@ static void ruby_runtime_stack_callback(
196190
};
197191
emit_frame(&marker_frame);
198192

199-
// Try to get current thread and execution context safely
200193
VALUE current_thread = rb_thread_current();
201194
if (current_thread == Qnil) return;
202195

@@ -222,40 +215,43 @@ static void ruby_runtime_stack_callback(
222215

223216
if (!cfp || !end_cfp) return;
224217

225-
// Skip dummy frames
226218
end_cfp = RUBY_VM_NEXT_CONTROL_FRAME(end_cfp);
227219
if (end_cfp <= cfp) return;
228220

229-
// Walk stack frames with extreme caution
230221
int frame_count = 0;
231-
const int MAX_FRAMES = 10; // Keep very low to minimize crash risk
222+
const int MAX_FRAMES = 15;
232223

233224
for (; cfp != RUBY_VM_NEXT_CONTROL_FRAME(end_cfp) && frame_count < MAX_FRAMES;
234225
cfp = RUBY_VM_NEXT_CONTROL_FRAME(cfp)) {
235226

236227
if (VM_FRAME_RUBYFRAME_P(cfp) && cfp->iseq) {
237-
// Instead of calling rb_iseq_* functions, work directly with iseq struct
238228
const rb_iseq_t *iseq = cfp->iseq;
239229

240-
// Basic frame info without risky API calls
241-
char frame_desc[64];
242-
snprintf(frame_desc, sizeof(frame_desc), "ruby_frame_%d", frame_count);
230+
VALUE name = rb_iseq_base_label(iseq);
231+
const char *function_name = (name != Qnil) ? RSTRING_PTR(name) : "<unknown>";
243232

244-
// Try to get basic line info safely using direct struct access
233+
VALUE filename = rb_iseq_path(iseq);
234+
const char *file_name = (filename != Qnil) ? RSTRING_PTR(filename) : "<unknown>";
235+
236+
// Calculate line number using direct struct access
245237
int line_no = 0;
246238
if (iseq && cfp->pc) {
247-
// Use direct access to iseq body instead of helper functions
248239
if (iseq->body && iseq->body->iseq_encoded && iseq->body->iseq_size > 0) {
249240
ptrdiff_t pc_offset = cfp->pc - iseq->body->iseq_encoded;
250241
if (pc_offset >= 0 && pc_offset < iseq->body->iseq_size) {
251-
line_no = frame_count + 1; // Use frame position as approximation
242+
// Use the Ruby VM line calculation like ddtrace_rb_profile_frames
243+
size_t pos = pc_offset;
244+
if (pos > 0) {
245+
pos--; // Use pos-1 because PC points next instruction
246+
}
247+
line_no = rb_iseq_line_no(iseq, pos);
252248
}
253249
}
254250
}
255251

256252
ddog_crasht_RuntimeStackFrame frame = {
257-
.function_name = frame_desc,
258-
.file_name = "ruby_source.rb",
253+
.function_name = function_name,
254+
.file_name = file_name,
259255
.line_number = line_no,
260256
.column_number = 0
261257
};
@@ -264,15 +260,6 @@ static void ruby_runtime_stack_callback(
264260
frame_count++;
265261
}
266262
}
267-
268-
// Emit end marker
269-
ddog_crasht_RuntimeStackFrame end_frame = {
270-
.function_name = "ruby_stack_walker_end",
271-
.file_name = "crashtracker.c",
272-
.line_number = frame_count,
273-
.column_number = 0
274-
};
275-
emit_frame(&end_frame);
276263
}
277264

278265
static VALUE _native_register_runtime_stack_callback(DDTRACE_UNUSED VALUE _self, VALUE callback_type) {

spec/datadog/core/crashtracking/component_spec.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@
240240
crash_tracker.start
241241
trigger.call
242242
end
243-
puts(crash_report_experimental)
243+
puts(crash_report_experimental.to_json)
244244
puts(log_messages)
245245
expect(stack_trace).to match(array_including(hash_including(function: function)))
246246
expect(stack_trace.size).to be > 10
@@ -348,7 +348,6 @@
348348
end
349349
end
350350

351-
352351
describe '#runtime_callback_registered?' do
353352
it 'returns true when callback is registered' do
354353
crashtracker = build_crashtracker(logger: logger)

0 commit comments

Comments
 (0)