Skip to content

Conversation

@marcotc
Copy link
Member

@marcotc marcotc commented Nov 21, 2025

What does this PR do?

Notable caveats:

  • Errno didn't need to be changed: Errno errors encode their error information in the class name (which is already reported), thus there's no need to add new information for telemetry purposes.

Motivation:

Change log entry

Additional Notes:

How to test the change?

bouwkast and others added 26 commits November 7, 2025 11:40
This gets us closer to allowing these errors to be
sent to telemetry.
Add ruby_helpers.h include to 8 C files that use datadog_profiling_error_class
and datadog_profiling_internal_error_class but were missing the header declaration.

This fixes the compilation error:
  error: 'datadog_profiling_error_class' undeclared

Files fixed:
- clock_id_from_pthread.c
- collectors_gc_profiling_helper.c
- collectors_stack.c
- collectors_thread_context.c
- encoded_profile.c
- libdatadog_helpers.c
- private_vm_api_access.c
- unsafe_api_calls_check.c
Move ruby_helpers.h include after private VM headers to avoid conflicts.
This file requires private VM headers to be included first before any
public Ruby headers, but ruby_helpers.h includes datadog_ruby_common.h
which includes ruby.h, causing header ordering conflicts.

Fixes compilation error: 'expected ')' before '==' token in RHASH_EMPTY_P'
Cannot include ruby_helpers.h in this file as it pulls in public Ruby headers
(via datadog_ruby_common.h) that conflict with private VM headers.

Instead, declare the exception class globals as extern, following the pattern
already established in this file for other declarations.

This fully resolves the header ordering compilation error.
Method was renamed from safe_exception_message to constant_exception_message
but the RBS signature file was not updated, causing Steep type errors.
The error method must be public but was accidentally made private when
constant_exception_message was added. Moving it before the private keyword
restores its public visibility.

Fixes test failure: NoMethodError: private method 'error' called
Serialization errors contain dynamic libdatadog content, so they should
raise ProfilingInternalError (not ProfilingError or RuntimeError).

Updated both the Ruby wrapper code and the test expectation to use
ProfilingInternalError consistently.

Fixes test failure expecting ProfilingError but getting RuntimeError.
Signed-off-by: Marco Costa <[email protected]>
Signed-off-by: Marco Costa <[email protected]>
Signed-off-by: Marco Costa <[email protected]>
Signed-off-by: Marco Costa <[email protected]>
@github-actions github-actions bot added core Involves Datadog core libraries profiling Involves Datadog profiling labels Nov 21, 2025
@pr-commenter
Copy link

pr-commenter bot commented Nov 21, 2025

Benchmarks

Benchmark execution time: 2025-11-26 00:51:30

Comparing candidate commit 5432e65 in PR branch marcotc/error-logs-remediation-custom-profiler-code with baseline commit ae94edc in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 44 metrics, 2 unstable metrics.

These files had extensive line wrapping/reformatting that has been reverted.
Content changes (include reordering and commented rb_raise calls) have been preserved.
@marcotc marcotc force-pushed the marcotc/error-logs-remediation-custom-profiler-code branch from ef1db55 to b7edd96 Compare November 21, 2025 01:14
Copy link
Member

@ivoanjo ivoanjo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this! Did a pass :)

Comment on lines 49 to 59
extern VALUE eNativeRuntimeError;
extern VALUE eNativeArgumentError;
extern VALUE eNativeTypeError;
// Declare exception class globals from ruby_helpers.h
// (We can't include ruby_helpers.h here as it pulls in public Ruby headers that conflict with private VM headers)
#define raise_error(native_exception_class, fmt, ...) \
_raise_error(native_exception_class, "" fmt, ##__VA_ARGS__)
NORETURN(
void _raise_error(VALUE native_exception_class, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this file is kinda... always a pain. TBH maybe it's easy to just not change anything here -- we'll miss exceptions from this file, but they're rare-ish so I'm not sure we care.

Either that or perhaps having a very simple extern raise_native_error(char *); that gets exported elsewhere and that this class uses directly (so this class doesn't get to pick the specific exception class or template stuff -- always get a native error + a static string)"?

Comment on lines 40 to 42
if (sigaction(SIGPROF, &signal_handler_config, &existing_signal_handler_config) != 0) {
rb_exc_raise(rb_syserr_new_str(errno, rb_sprintf("Could not install profiling signal handler (%s)", handler_pretty_name)));
raise_syserr(errno, true, "Could not install profiling signal handler", __FILE__, __LINE__, handler_pretty_name);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm passing in handler_pretty_name as the function name argument to raise_syserr is... a bit weird. Is it a problem to template this string?

If needed, I'm thinking we can turn this into an enum -- we always know which handler_pretty_names are allowed, since it's all in the code anyway...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this was like a the last call site I had to "fix" and I think I just tried to fit it in the existing methods.
I'll see I can try the enum so I don't bastardize it.

handler_pretty_name
)
)
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⬆️ The rb_exc_raise on line 59 one possibly needs to change to match the others 👀

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing some of the shared error code may need to move to datadog_ruby_common.h/.c so it can be used here too...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is slightly outdated vs what's there in profiling.rb right now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't do all the janitorial work 😛. I'll keep this comment open as a reminder.

@github-actions
Copy link

github-actions bot commented Nov 25, 2025

Typing analysis

Note: Ignored files are excluded from the next sections.

Untyped methods

This PR introduces 1 untyped method and 1 partially typed method, and clears 1 partially typed method. It decreases the percentage of typed methods from 54.48% to 54.47% (-0.01%).

Untyped methods (+1-0)Introduced:
sig/datadog/profiling.rbs:5
└── def initialize: (*untyped args, **untyped kwargs) -> void
Partially typed methods (+1-1)Introduced:
sig/datadog/profiling.rbs:20
└── def self.try_reading_skipped_reason_file: (?untyped file_api) -> ::String?
Cleared:
sig/datadog/profiling.rbs:14
└── def self.try_reading_skipped_reason_file: (?untyped file_api) -> ::String?

If you believe a method or an attribute is rightfully untyped or partially typed, you can add # untyped:accept to the end of the line to remove it from the stats.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Involves Datadog core libraries profiling Involves Datadog profiling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants