ddtrace 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +70 -0
- data/LICENSE-3rdparty.csv +2 -0
- data/README.md +1 -1
- data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +1 -1
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +9 -2
- data/ext/ddtrace_profiling_native_extension/clock_id.h +20 -0
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +30 -1
- data/ext/ddtrace_profiling_native_extension/clock_id_noop.c +10 -1
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +152 -31
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +6 -0
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +391 -0
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +11 -7
- data/ext/ddtrace_profiling_native_extension/extconf.rb +26 -19
- data/ext/ddtrace_profiling_native_extension/helpers.h +12 -0
- data/ext/ddtrace_profiling_native_extension/http_transport.c +40 -47
- data/ext/ddtrace_profiling_native_extension/{libddprof_helpers.h → libdatadog_helpers.h} +2 -1
- data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +36 -20
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +39 -29
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +2 -5
- data/ext/ddtrace_profiling_native_extension/profiling.c +4 -3
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +25 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +33 -1
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +294 -19
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +9 -8
- data/lib/datadog/appsec/autoload.rb +4 -2
- data/lib/datadog/appsec/configuration.rb +1 -1
- data/lib/datadog/appsec/contrib/auto_instrument.rb +0 -2
- data/lib/datadog/appsec/contrib/configuration/settings.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/configuration/settings.rb +2 -2
- data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +6 -6
- data/lib/datadog/appsec/contrib/rack/integration.rb +5 -5
- data/lib/datadog/appsec/contrib/rack/patcher.rb +2 -2
- data/lib/datadog/appsec/contrib/rack/reactive/request.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/reactive/response.rb +1 -1
- data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +2 -2
- data/lib/datadog/appsec/contrib/rack/request_middleware.rb +3 -3
- data/lib/datadog/appsec/contrib/rails/configuration/settings.rb +2 -2
- data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +4 -4
- data/lib/datadog/appsec/contrib/rails/integration.rb +4 -4
- data/lib/datadog/appsec/contrib/rails/patcher.rb +16 -12
- data/lib/datadog/appsec/contrib/rails/reactive/action.rb +1 -1
- data/lib/datadog/appsec/contrib/sinatra/configuration/settings.rb +2 -2
- data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +5 -5
- data/lib/datadog/appsec/contrib/sinatra/integration.rb +4 -4
- data/lib/datadog/appsec/contrib/sinatra/patcher.rb +16 -12
- data/lib/datadog/appsec/event.rb +3 -3
- data/lib/datadog/appsec/extensions.rb +1 -1
- data/lib/datadog/appsec/processor.rb +1 -1
- data/lib/datadog/appsec/reactive/engine.rb +2 -2
- data/lib/datadog/appsec/reactive/operation.rb +3 -3
- data/lib/datadog/appsec.rb +5 -5
- data/lib/datadog/ci/configuration/components.rb +1 -1
- data/lib/datadog/ci/configuration/settings.rb +1 -1
- data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +2 -2
- data/lib/datadog/ci/contrib/cucumber/formatter.rb +5 -5
- data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +1 -1
- data/lib/datadog/ci/contrib/cucumber/integration.rb +4 -4
- data/lib/datadog/ci/contrib/cucumber/patcher.rb +2 -2
- data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +2 -2
- data/lib/datadog/ci/contrib/rspec/example.rb +5 -5
- data/lib/datadog/ci/contrib/rspec/integration.rb +4 -4
- data/lib/datadog/ci/contrib/rspec/patcher.rb +2 -2
- data/lib/datadog/ci/ext/environment.rb +8 -6
- data/lib/datadog/ci/extensions.rb +4 -4
- data/lib/datadog/ci/flush.rb +2 -2
- data/lib/datadog/ci/test.rb +3 -3
- data/lib/datadog/ci.rb +6 -6
- data/lib/datadog/core/buffer/cruby.rb +1 -1
- data/lib/datadog/core/buffer/thread_safe.rb +1 -1
- data/lib/datadog/core/configuration/agent_settings_resolver.rb +6 -6
- data/lib/datadog/core/configuration/base.rb +11 -2
- data/lib/datadog/core/configuration/components.rb +51 -48
- data/lib/datadog/core/configuration/option_definition.rb +1 -1
- data/lib/datadog/core/configuration/option_definition_set.rb +1 -1
- data/lib/datadog/core/configuration/options.rb +3 -3
- data/lib/datadog/core/configuration/settings.rb +34 -7
- data/lib/datadog/core/configuration.rb +8 -5
- data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
- data/lib/datadog/core/diagnostics/health.rb +2 -2
- data/lib/datadog/core/environment/cgroup.rb +1 -1
- data/lib/datadog/core/environment/container.rb +1 -1
- data/lib/datadog/core/environment/ext.rb +1 -1
- data/lib/datadog/core/environment/identity.rb +2 -2
- data/lib/datadog/core/environment/platform.rb +1 -1
- data/lib/datadog/core/environment/socket.rb +1 -1
- data/lib/datadog/core/error.rb +1 -1
- data/lib/datadog/core/extensions.rb +1 -1
- data/lib/datadog/core/metrics/client.rb +8 -8
- data/lib/datadog/core/metrics/options.rb +3 -3
- data/lib/datadog/core/runtime/metrics.rb +6 -6
- data/lib/datadog/core/telemetry/client.rb +79 -0
- data/lib/datadog/core/telemetry/collector.rb +234 -0
- data/lib/datadog/core/telemetry/emitter.rb +48 -0
- data/lib/datadog/core/telemetry/event.rb +71 -0
- data/lib/datadog/core/telemetry/ext.rb +11 -0
- data/lib/datadog/core/telemetry/heartbeat.rb +37 -0
- data/lib/datadog/core/telemetry/http/adapters/net.rb +113 -0
- data/lib/datadog/core/telemetry/http/env.rb +20 -0
- data/lib/datadog/core/telemetry/http/ext.rb +20 -0
- data/lib/datadog/core/telemetry/http/response.rb +68 -0
- data/lib/datadog/core/telemetry/http/transport.rb +53 -0
- data/lib/datadog/core/telemetry/v1/app_event.rb +52 -0
- data/lib/datadog/core/telemetry/v1/application.rb +86 -0
- data/lib/datadog/core/telemetry/v1/configuration.rb +25 -0
- data/lib/datadog/core/telemetry/v1/dependency.rb +36 -0
- data/lib/datadog/core/telemetry/v1/host.rb +51 -0
- data/lib/datadog/core/telemetry/v1/integration.rb +58 -0
- data/lib/datadog/core/telemetry/v1/product.rb +28 -0
- data/lib/datadog/core/telemetry/v1/telemetry_request.rb +100 -0
- data/lib/datadog/core/utils/object_set.rb +1 -1
- data/lib/datadog/core/utils/sequence.rb +5 -0
- data/lib/datadog/core/utils/string_table.rb +1 -1
- data/lib/datadog/core/utils/time.rb +3 -3
- data/lib/datadog/core/utils.rb +2 -2
- data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +2 -2
- data/lib/datadog/core/vendor/multipart-post/net/http/post/multipart.rb +3 -3
- data/lib/datadog/core/workers/async.rb +1 -1
- data/lib/datadog/core/workers/polling.rb +2 -2
- data/lib/datadog/core/workers/runtime_metrics.rb +4 -4
- data/lib/datadog/core.rb +50 -50
- data/lib/datadog/kit.rb +1 -1
- data/lib/datadog/opentracer/distributed_headers.rb +2 -2
- data/lib/datadog/opentracer/rack_propagator.rb +11 -7
- data/lib/datadog/opentracer/span.rb +1 -1
- data/lib/datadog/opentracer/text_map_propagator.rb +9 -6
- data/lib/datadog/opentracer/thread_local_scope_manager.rb +1 -1
- data/lib/datadog/opentracer/tracer.rb +19 -15
- data/lib/datadog/opentracer.rb +16 -16
- data/lib/datadog/profiling/buffer.rb +3 -3
- data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +4 -19
- data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +74 -0
- data/lib/datadog/profiling/collectors/old_stack.rb +7 -7
- data/lib/datadog/profiling/collectors/stack.rb +3 -8
- data/lib/datadog/profiling/encoding/profile.rb +1 -1
- data/lib/datadog/profiling/events/stack.rb +1 -1
- data/lib/datadog/profiling/exporter.rb +17 -9
- data/lib/datadog/profiling/ext/forking.rb +36 -37
- data/lib/datadog/profiling/ext.rb +1 -0
- data/lib/datadog/profiling/flush.rb +0 -3
- data/lib/datadog/profiling/http_transport.rb +4 -3
- data/lib/datadog/profiling/old_recorder.rb +2 -7
- data/lib/datadog/profiling/pprof/builder.rb +4 -4
- data/lib/datadog/profiling/pprof/converter.rb +1 -1
- data/lib/datadog/profiling/pprof/message_set.rb +1 -1
- data/lib/datadog/profiling/pprof/stack_sample.rb +4 -4
- data/lib/datadog/profiling/pprof/string_table.rb +1 -1
- data/lib/datadog/profiling/pprof/template.rb +5 -5
- data/lib/datadog/profiling/preload.rb +1 -1
- data/lib/datadog/profiling/scheduler.rb +5 -4
- data/lib/datadog/profiling/stack_recorder.rb +14 -4
- data/lib/datadog/profiling/tag_builder.rb +6 -1
- data/lib/datadog/profiling/tasks/setup.rb +2 -2
- data/lib/datadog/profiling/trace_identifiers/ddtrace.rb +2 -2
- data/lib/datadog/profiling/trace_identifiers/helper.rb +1 -1
- data/lib/datadog/profiling/transport/http/api/endpoint.rb +5 -5
- data/lib/datadog/profiling/transport/http/api/instance.rb +2 -2
- data/lib/datadog/profiling/transport/http/api/spec.rb +1 -1
- data/lib/datadog/profiling/transport/http/api.rb +5 -5
- data/lib/datadog/profiling/transport/http/builder.rb +3 -3
- data/lib/datadog/profiling/transport/http/client.rb +2 -2
- data/lib/datadog/profiling/transport/http/response.rb +1 -1
- data/lib/datadog/profiling/transport/http.rb +21 -15
- data/lib/datadog/profiling.rb +21 -20
- data/lib/datadog/tracing/analytics.rb +1 -1
- data/lib/datadog/tracing/buffer.rb +5 -5
- data/lib/datadog/tracing/context.rb +1 -1
- data/lib/datadog/tracing/context_provider.rb +2 -2
- data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/action_cable/event.rb +4 -5
- data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +4 -4
- data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +3 -3
- data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +4 -4
- data/lib/datadog/tracing/contrib/action_cable/events.rb +4 -4
- data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +3 -4
- data/lib/datadog/tracing/contrib/action_cable/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/action_cable/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/action_mailer/event.rb +3 -3
- data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +3 -3
- data/lib/datadog/tracing/contrib/action_mailer/events/process.rb +3 -3
- data/lib/datadog/tracing/contrib/action_mailer/events.rb +2 -2
- data/lib/datadog/tracing/contrib/action_mailer/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/action_mailer/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +6 -6
- data/lib/datadog/tracing/contrib/action_pack/action_controller/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/action_pack/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/action_pack/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/action_pack/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/action_view/event.rb +1 -1
- data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +5 -5
- data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +5 -5
- data/lib/datadog/tracing/contrib/action_view/events.rb +2 -2
- data/lib/datadog/tracing/contrib/action_view/instrumentation/partial_renderer.rb +2 -2
- data/lib/datadog/tracing/contrib/action_view/instrumentation/template_renderer.rb +2 -2
- data/lib/datadog/tracing/contrib/action_view/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/action_view/patcher.rb +7 -7
- data/lib/datadog/tracing/contrib/action_view/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/active_job/event.rb +3 -3
- data/lib/datadog/tracing/contrib/active_job/events/discard.rb +4 -4
- data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +4 -4
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +4 -4
- data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +4 -4
- data/lib/datadog/tracing/contrib/active_job/events/perform.rb +4 -4
- data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +4 -4
- data/lib/datadog/tracing/contrib/active_job/events.rb +6 -6
- data/lib/datadog/tracing/contrib/active_job/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/active_job/log_injection.rb +0 -2
- data/lib/datadog/tracing/contrib/active_job/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/active_model_serializers/event.rb +4 -5
- data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +3 -3
- data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +2 -2
- data/lib/datadog/tracing/contrib/active_model_serializers/events.rb +2 -2
- data/lib/datadog/tracing/contrib/active_model_serializers/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/active_model_serializers/patcher.rb +3 -4
- data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
- data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/active_record/event.rb +1 -1
- data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +4 -4
- data/lib/datadog/tracing/contrib/active_record/events/sql.rb +6 -6
- data/lib/datadog/tracing/contrib/active_record/events.rb +2 -2
- data/lib/datadog/tracing/contrib/active_record/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/active_record/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/active_record/utils.rb +2 -2
- data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +19 -9
- data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -5
- data/lib/datadog/tracing/contrib/active_support/notifications/event.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/notifications/subscriber.rb +1 -1
- data/lib/datadog/tracing/contrib/active_support/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/analytics.rb +1 -1
- data/lib/datadog/tracing/contrib/auto_instrument.rb +4 -4
- data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/aws/instrumentation.rb +3 -4
- data/lib/datadog/tracing/contrib/aws/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/aws/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +1 -1
- data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/concurrent_ruby/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/configurable.rb +2 -2
- data/lib/datadog/tracing/contrib/configuration/resolvers/pattern_resolver.rb +1 -1
- data/lib/datadog/tracing/contrib/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +4 -5
- data/lib/datadog/tracing/contrib/dalli/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/dalli/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/dalli/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/delayed_job/ext.rb +2 -0
- data/lib/datadog/tracing/contrib/delayed_job/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/delayed_job/patcher.rb +8 -2
- data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +3 -4
- data/lib/datadog/tracing/contrib/delayed_job/server_internal_tracer/worker.rb +32 -0
- data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/elasticsearch/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -7
- data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +1 -1
- data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
- data/lib/datadog/tracing/contrib/ethon/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +3 -4
- data/lib/datadog/tracing/contrib/ethon/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/excon/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/excon/middleware.rb +6 -7
- data/lib/datadog/tracing/contrib/excon/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/extensions.rb +5 -3
- data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/faraday/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -6
- data/lib/datadog/tracing/contrib/faraday/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/grape/endpoint.rb +4 -5
- data/lib/datadog/tracing/contrib/grape/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/grape/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/graphql/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/graphql/patcher.rb +2 -3
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +13 -4
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +6 -6
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +3 -4
- data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/grpc/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +1 -2
- data/lib/datadog/tracing/contrib/http/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/http/instrumentation.rb +3 -4
- data/lib/datadog/tracing/contrib/http/integration.rb +6 -6
- data/lib/datadog/tracing/contrib/http/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +4 -5
- data/lib/datadog/tracing/contrib/httpclient/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/httpclient/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +4 -5
- data/lib/datadog/tracing/contrib/httprb/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/httprb/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/event.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/connection/request.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_batch.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer/process_message.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/heartbeat.rb +4 -4
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/join_group.rb +4 -4
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/leave_group.rb +4 -4
- data/lib/datadog/tracing/contrib/kafka/events/consumer_group/sync_group.rb +4 -4
- data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +2 -2
- data/lib/datadog/tracing/contrib/kafka/events.rb +9 -9
- data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/kafka/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +1 -2
- data/lib/datadog/tracing/contrib/lograge/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/lograge/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/mongodb/instrumentation.rb +3 -3
- data/lib/datadog/tracing/contrib/mongodb/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/mongodb/parsers.rb +1 -1
- data/lib/datadog/tracing/contrib/mongodb/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +4 -4
- data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +3 -4
- data/lib/datadog/tracing/contrib/mysql2/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/mysql2/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/patcher.rb +13 -2
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +3 -4
- data/lib/datadog/tracing/contrib/pg/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/pg/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/presto/instrumentation.rb +2 -3
- data/lib/datadog/tracing/contrib/presto/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/presto/patcher.rb +4 -4
- data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/qless/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/qless/patcher.rb +1 -2
- data/lib/datadog/tracing/contrib/qless/qless_job.rb +2 -3
- data/lib/datadog/tracing/contrib/qless/tracer_cleaner.rb +0 -2
- data/lib/datadog/tracing/contrib/que/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/que/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/que/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/que/tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/racecar/event.rb +4 -5
- data/lib/datadog/tracing/contrib/racecar/events/batch.rb +2 -2
- data/lib/datadog/tracing/contrib/racecar/events/consume.rb +2 -2
- data/lib/datadog/tracing/contrib/racecar/events/message.rb +2 -2
- data/lib/datadog/tracing/contrib/racecar/events.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/racecar/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/rack/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/rack/middlewares.rb +24 -20
- data/lib/datadog/tracing/contrib/rack/patcher.rb +12 -2
- data/lib/datadog/tracing/contrib/rails/auto_instrument_railtie.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +1 -1
- data/lib/datadog/tracing/contrib/rails/framework.rb +16 -21
- data/lib/datadog/tracing/contrib/rails/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/rails/log_injection.rb +0 -2
- data/lib/datadog/tracing/contrib/rails/middlewares.rb +1 -2
- data/lib/datadog/tracing/contrib/rails/patcher.rb +7 -8
- data/lib/datadog/tracing/contrib/rails/railtie.rb +3 -3
- data/lib/datadog/tracing/contrib/rails/utils.rb +1 -1
- data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +17 -2
- data/lib/datadog/tracing/contrib/rake/instrumentation.rb +12 -7
- data/lib/datadog/tracing/contrib/rake/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/rake/patcher.rb +3 -4
- data/lib/datadog/tracing/contrib/redis/configuration/resolver.rb +1 -1
- data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/redis/instrumentation.rb +6 -7
- data/lib/datadog/tracing/contrib/redis/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/redis/patcher.rb +6 -6
- data/lib/datadog/tracing/contrib/redis/tags.rb +3 -4
- data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/resque/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/resque/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/resque/resque_job.rb +3 -4
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/rest_client/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +4 -5
- data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +1 -2
- data/lib/datadog/tracing/contrib/semantic_logger/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/semantic_logger/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/sequel/database.rb +4 -5
- data/lib/datadog/tracing/contrib/sequel/dataset.rb +4 -5
- data/lib/datadog/tracing/contrib/sequel/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/sequel/patcher.rb +3 -3
- data/lib/datadog/tracing/contrib/sequel/utils.rb +2 -2
- data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/shoryuken/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/shoryuken/patcher.rb +1 -1
- data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +1 -1
- data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +4 -5
- data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +3 -3
- data/lib/datadog/tracing/contrib/sidekiq/ext.rb +6 -0
- data/lib/datadog/tracing/contrib/sidekiq/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/sidekiq/patcher.rb +14 -7
- data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/heartbeat.rb +19 -1
- data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/{scheduled_push.rb → redis_info.rb} +5 -6
- data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/scheduled_poller.rb +53 -0
- data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -6
- data/lib/datadog/tracing/contrib/sidekiq/tracing.rb +2 -2
- data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/sinatra/env.rb +2 -2
- data/lib/datadog/tracing/contrib/sinatra/framework.rb +0 -2
- data/lib/datadog/tracing/contrib/sinatra/headers.rb +1 -1
- data/lib/datadog/tracing/contrib/sinatra/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/sinatra/patcher.rb +5 -5
- data/lib/datadog/tracing/contrib/sinatra/tracer.rb +7 -8
- data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +6 -7
- data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/sneakers/integration.rb +4 -4
- data/lib/datadog/tracing/contrib/sneakers/patcher.rb +2 -2
- data/lib/datadog/tracing/contrib/sneakers/tracer.rb +2 -3
- data/lib/datadog/tracing/contrib/status_code_matcher.rb +2 -2
- data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +2 -2
- data/lib/datadog/tracing/contrib/sucker_punch/instrumentation.rb +3 -4
- data/lib/datadog/tracing/contrib/sucker_punch/integration.rb +3 -3
- data/lib/datadog/tracing/contrib/sucker_punch/patcher.rb +4 -5
- data/lib/datadog/tracing/contrib.rb +48 -48
- data/lib/datadog/tracing/correlation.rb +1 -1
- data/lib/datadog/tracing/distributed/headers/b3.rb +4 -4
- data/lib/datadog/tracing/distributed/headers/b3_single.rb +4 -4
- data/lib/datadog/tracing/distributed/headers/datadog.rb +3 -3
- data/lib/datadog/tracing/distributed/headers/parser.rb +1 -1
- data/lib/datadog/tracing/distributed/helpers.rb +2 -2
- data/lib/datadog/tracing/distributed/metadata/b3.rb +4 -4
- data/lib/datadog/tracing/distributed/metadata/b3_single.rb +4 -4
- data/lib/datadog/tracing/distributed/metadata/datadog.rb +2 -2
- data/lib/datadog/tracing/distributed/metadata/parser.rb +1 -1
- data/lib/datadog/tracing/event.rb +1 -1
- data/lib/datadog/tracing/metadata/analytics.rb +2 -2
- data/lib/datadog/tracing/metadata/errors.rb +2 -2
- data/lib/datadog/tracing/metadata/tagging.rb +2 -2
- data/lib/datadog/tracing/metadata.rb +3 -3
- data/lib/datadog/tracing/pipeline/span_filter.rb +10 -6
- data/lib/datadog/tracing/pipeline.rb +3 -3
- data/lib/datadog/tracing/propagation/grpc.rb +6 -6
- data/lib/datadog/tracing/propagation/http.rb +8 -8
- data/lib/datadog/tracing/runtime/metrics.rb +1 -1
- data/lib/datadog/tracing/sampling/all_sampler.rb +1 -1
- data/lib/datadog/tracing/sampling/priority_sampler.rb +5 -5
- data/lib/datadog/tracing/sampling/rate_by_key_sampler.rb +2 -2
- data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +3 -3
- data/lib/datadog/tracing/sampling/rate_limiter.rb +1 -1
- data/lib/datadog/tracing/sampling/rate_sampler.rb +5 -5
- data/lib/datadog/tracing/sampling/rule.rb +3 -3
- data/lib/datadog/tracing/sampling/rule_sampler.rb +4 -4
- data/lib/datadog/tracing/span.rb +4 -4
- data/lib/datadog/tracing/span_operation.rb +9 -9
- data/lib/datadog/tracing/sync_writer.rb +5 -5
- data/lib/datadog/tracing/trace_operation.rb +16 -9
- data/lib/datadog/tracing/trace_segment.rb +5 -5
- data/lib/datadog/tracing/tracer.rb +15 -15
- data/lib/datadog/tracing/workers/trace_writer.rb +9 -9
- data/lib/datadog/tracing/workers.rb +3 -3
- data/lib/datadog/tracing/writer.rb +5 -5
- data/lib/datadog/tracing.rb +8 -8
- data/lib/ddtrace/auto_instrument.rb +9 -2
- data/lib/ddtrace/transport/ext.rb +7 -1
- data/lib/ddtrace/transport/http/adapters/net.rb +3 -2
- data/lib/ddtrace/transport/http/adapters/test.rb +1 -1
- data/lib/ddtrace/transport/http/adapters/unix_socket.rb +2 -2
- data/lib/ddtrace/transport/http/api/map.rb +1 -1
- data/lib/ddtrace/transport/http/api.rb +4 -4
- data/lib/ddtrace/transport/http/builder.rb +5 -5
- data/lib/ddtrace/transport/http/client.rb +2 -2
- data/lib/ddtrace/transport/http/response.rb +1 -1
- data/lib/ddtrace/transport/http/statistics.rb +1 -1
- data/lib/ddtrace/transport/http/traces.rb +5 -5
- data/lib/ddtrace/transport/http.rb +12 -9
- data/lib/ddtrace/transport/io/client.rb +2 -2
- data/lib/ddtrace/transport/io/response.rb +1 -1
- data/lib/ddtrace/transport/io/traces.rb +3 -3
- data/lib/ddtrace/transport/io.rb +3 -3
- data/lib/ddtrace/transport/statistics.rb +2 -2
- data/lib/ddtrace/transport/trace_formatter.rb +5 -5
- data/lib/ddtrace/transport/traces.rb +5 -5
- data/lib/ddtrace/version.rb +1 -1
- data/lib/ddtrace.rb +6 -6
- metadata +35 -22
- data/.editorconfig +0 -22
- data/.gitignore +0 -58
- data/CONTRIBUTING.md +0 -81
- data/ddtrace.gemspec +0 -71
- data/docs/0.x-trace.png +0 -0
- data/docs/1.0-trace.png +0 -0
- data/docs/AutoInstrumentation.md +0 -36
- data/docs/Deprecation.md +0 -8
- data/docs/DevelopmentGuide.md +0 -259
- data/docs/GettingStarted.md +0 -2712
- data/docs/ProfilingDevelopment.md +0 -109
- data/docs/PublicApi.md +0 -14
- data/docs/UpgradeGuide.md +0 -736
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
#include <ruby.h>
|
|
2
|
+
#include <ruby/thread.h>
|
|
3
|
+
#include <ruby/thread_native.h>
|
|
4
|
+
#include <ruby/debug.h>
|
|
5
|
+
#include <stdbool.h>
|
|
6
|
+
#include <signal.h>
|
|
7
|
+
#include "helpers.h"
|
|
8
|
+
#include "ruby_helpers.h"
|
|
9
|
+
#include "collectors_cpu_and_wall_time.h"
|
|
10
|
+
#include "private_vm_api_access.h"
|
|
11
|
+
|
|
12
|
+
// Used to trigger the periodic execution of Collectors::CpuAndWallTime, which implements all of the sampling logic
|
|
13
|
+
// itself; this class only implements the "doing it periodically" part.
|
|
14
|
+
//
|
|
15
|
+
// This file implements the native bits of the Datadog::Profiling::Collectors::CpuAndWallTimeWorker class
|
|
16
|
+
|
|
17
|
+
// ---
|
|
18
|
+
// Here be dragons: This component is quite fiddly and probably one of the more complex in the profiler as it deals with
|
|
19
|
+
// multiple threads, signal handlers, global state, etc.
|
|
20
|
+
//
|
|
21
|
+
// ## Design notes for this class:
|
|
22
|
+
//
|
|
23
|
+
// ### Constraints
|
|
24
|
+
//
|
|
25
|
+
// Currently, sampling Ruby threads requires calling Ruby VM APIs that are only safe to call while holding on to the
|
|
26
|
+
// global VM lock (and are not async-signal safe -- cannot be called from a signal handler).
|
|
27
|
+
//
|
|
28
|
+
// @ivoanjo: As a note, I don't think we should think of this constraint as set in stone. Since can reach into the Ruby
|
|
29
|
+
// internals, we may be able to figure out a way of overcoming it. But it's definitely going to be hard so for now
|
|
30
|
+
// we're considering it as a given.
|
|
31
|
+
//
|
|
32
|
+
// ### Flow for triggering samples
|
|
33
|
+
//
|
|
34
|
+
// The flow for triggering samples is as follows:
|
|
35
|
+
//
|
|
36
|
+
// 1. Inside the `run_sampling_trigger_loop` function (running in the `CpuAndWallTimeWorker` background thread),
|
|
37
|
+
// a `SIGPROF` signal gets sent to the current process.
|
|
38
|
+
//
|
|
39
|
+
// 2. The `handle_sampling_signal` signal handler function gets called to handle the `SIGPROF` signal.
|
|
40
|
+
//
|
|
41
|
+
// Which thread the signal handler function gets called on by the operating system is quite important. We need to perform
|
|
42
|
+
// an operation -- calling the `rb_postponed_job_register_one` API -- that can only be called from the thread that
|
|
43
|
+
// is holding on to the global VM lock. So this is the thread we're "hoping" our signal lands on.
|
|
44
|
+
//
|
|
45
|
+
// The signal never lands on the `CpuAndWallTimeWorker` background thread because we explicitly block it off from that
|
|
46
|
+
// thread in `block_sigprof_signal_handler_from_running_in_current_thread`.
|
|
47
|
+
//
|
|
48
|
+
// If the signal lands on a thread that is not holding onto the global VM lock, we can't proceed to the next step,
|
|
49
|
+
// and we need to restart the sampling flow from step 1. (There's still quite a few improvements we can make here,
|
|
50
|
+
// but this is the current state of the implementation).
|
|
51
|
+
//
|
|
52
|
+
// 3. Inside `handle_sampling_signal`, if it's getting executed by the Ruby thread that is holding the global VM lock,
|
|
53
|
+
// we can call `rb_postponed_job_register_one` to ask the Ruby VM to call our `sample_from_postponed_job` function
|
|
54
|
+
// "as soon as it can".
|
|
55
|
+
//
|
|
56
|
+
// 4. The Ruby VM calls our `sample_from_postponed_job` from a thread holding the global VM lock. A sample is recorded by
|
|
57
|
+
// calling `cpu_and_wall_time_collector_sample`.
|
|
58
|
+
//
|
|
59
|
+
// ---
|
|
60
|
+
|
|
61
|
+
// Contains state for a single CpuAndWallTimeWorker instance
|
|
62
|
+
struct cpu_and_wall_time_worker_state {
|
|
63
|
+
// Important: This is not atomic nor is it guaranteed to replace memory barriers and the like. Aka this works for
|
|
64
|
+
// telling the sampling trigger loop to stop, but if we ever need to communicate more, we should move to actual
|
|
65
|
+
// atomic operations. stdatomic.h seems a nice thing to reach out for.
|
|
66
|
+
volatile bool should_run;
|
|
67
|
+
|
|
68
|
+
VALUE cpu_and_wall_time_collector_instance;
|
|
69
|
+
// When something goes wrong during sampling, we record the Ruby exception here, so that it can be "re-raised" on
|
|
70
|
+
// the CpuAndWallTimeWorker thread
|
|
71
|
+
VALUE failure_exception;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
static VALUE _native_new(VALUE klass);
|
|
75
|
+
static VALUE _native_initialize(DDTRACE_UNUSED VALUE _self, VALUE self_instance, VALUE cpu_and_wall_time_collector_instance);
|
|
76
|
+
static void cpu_and_wall_time_worker_typed_data_mark(void *state_ptr);
|
|
77
|
+
static VALUE _native_sampling_loop(VALUE self, VALUE instance);
|
|
78
|
+
static VALUE _native_stop(DDTRACE_UNUSED VALUE _self, VALUE self_instance);
|
|
79
|
+
static void install_sigprof_signal_handler(void (*signal_handler_function)(int, siginfo_t *, void *));
|
|
80
|
+
static void remove_sigprof_signal_handler(void);
|
|
81
|
+
static void block_sigprof_signal_handler_from_running_in_current_thread(void);
|
|
82
|
+
static void handle_sampling_signal(DDTRACE_UNUSED int _signal, DDTRACE_UNUSED siginfo_t *_info, DDTRACE_UNUSED void *_ucontext);
|
|
83
|
+
static void *run_sampling_trigger_loop(void *state_ptr);
|
|
84
|
+
static void interrupt_sampling_trigger_loop(void *state_ptr);
|
|
85
|
+
static void sample_from_postponed_job(DDTRACE_UNUSED void *_unused);
|
|
86
|
+
static VALUE handle_sampling_failure(VALUE self_instance, VALUE exception);
|
|
87
|
+
static VALUE _native_current_sigprof_signal_handler(DDTRACE_UNUSED VALUE self);
|
|
88
|
+
static VALUE release_gvl_and_run_sampling_trigger_loop(VALUE instance);
|
|
89
|
+
static VALUE _native_is_running(DDTRACE_UNUSED VALUE self, VALUE instance);
|
|
90
|
+
static void testing_signal_handler(DDTRACE_UNUSED int _signal, DDTRACE_UNUSED siginfo_t *_info, DDTRACE_UNUSED void *_ucontext);
|
|
91
|
+
static VALUE _native_install_testing_signal_handler(DDTRACE_UNUSED VALUE self);
|
|
92
|
+
static VALUE _native_remove_testing_signal_handler(DDTRACE_UNUSED VALUE self);
|
|
93
|
+
|
|
94
|
+
// Global state -- be very careful when accessing or modifying it
|
|
95
|
+
|
|
96
|
+
// Note: Global state must only be mutated while holding the global VM lock (we piggy back on it to ensure correctness).
|
|
97
|
+
// The active_sampler_instance needs to be global because we access it from the signal handler.
|
|
98
|
+
static VALUE active_sampler_instance = Qnil;
|
|
99
|
+
// ...We also store active_sampler_owner_thread to be able to tell who the active_sampler_instance belongs to (and also
|
|
100
|
+
// to detect when it is outdated)
|
|
101
|
+
static VALUE active_sampler_owner_thread = Qnil;
|
|
102
|
+
|
|
103
|
+
void collectors_cpu_and_wall_time_worker_init(VALUE profiling_module) {
|
|
104
|
+
rb_global_variable(&active_sampler_instance);
|
|
105
|
+
rb_global_variable(&active_sampler_owner_thread);
|
|
106
|
+
|
|
107
|
+
VALUE collectors_module = rb_define_module_under(profiling_module, "Collectors");
|
|
108
|
+
VALUE collectors_cpu_and_wall_time_worker_class = rb_define_class_under(collectors_module, "CpuAndWallTimeWorker", rb_cObject);
|
|
109
|
+
// Hosts methods used for testing the native code using RSpec
|
|
110
|
+
VALUE testing_module = rb_define_module_under(collectors_cpu_and_wall_time_worker_class, "Testing");
|
|
111
|
+
|
|
112
|
+
// Instances of the CpuAndWallTimeWorker class are "TypedData" objects.
|
|
113
|
+
// "TypedData" objects are special objects in the Ruby VM that can wrap C structs.
|
|
114
|
+
// In this case, it wraps the cpu_and_wall_time_worker_state.
|
|
115
|
+
//
|
|
116
|
+
// Because Ruby doesn't know how to initialize native-level structs, we MUST override the allocation function for objects
|
|
117
|
+
// of this class so that we can manage this part. Not overriding or disabling the allocation function is a common
|
|
118
|
+
// gotcha for "TypedData" objects that can very easily lead to VM crashes, see for instance
|
|
119
|
+
// https://bugs.ruby-lang.org/issues/18007 for a discussion around this.
|
|
120
|
+
rb_define_alloc_func(collectors_cpu_and_wall_time_worker_class, _native_new);
|
|
121
|
+
|
|
122
|
+
rb_define_singleton_method(collectors_cpu_and_wall_time_worker_class, "_native_initialize", _native_initialize, 2);
|
|
123
|
+
rb_define_singleton_method(collectors_cpu_and_wall_time_worker_class, "_native_sampling_loop", _native_sampling_loop, 1);
|
|
124
|
+
rb_define_singleton_method(collectors_cpu_and_wall_time_worker_class, "_native_stop", _native_stop, 1);
|
|
125
|
+
rb_define_singleton_method(testing_module, "_native_current_sigprof_signal_handler", _native_current_sigprof_signal_handler, 0);
|
|
126
|
+
rb_define_singleton_method(testing_module, "_native_is_running?", _native_is_running, 1);
|
|
127
|
+
rb_define_singleton_method(testing_module, "_native_install_testing_signal_handler", _native_install_testing_signal_handler, 0);
|
|
128
|
+
rb_define_singleton_method(testing_module, "_native_remove_testing_signal_handler", _native_remove_testing_signal_handler, 0);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// This structure is used to define a Ruby object that stores a pointer to a struct cpu_and_wall_time_worker_state
|
|
132
|
+
// See also https://github.com/ruby/ruby/blob/master/doc/extension.rdoc for how this works
|
|
133
|
+
static const rb_data_type_t cpu_and_wall_time_worker_typed_data = {
|
|
134
|
+
.wrap_struct_name = "Datadog::Profiling::Collectors::CpuAndWallTimeWorker",
|
|
135
|
+
.function = {
|
|
136
|
+
.dmark = cpu_and_wall_time_worker_typed_data_mark,
|
|
137
|
+
.dfree = RUBY_DEFAULT_FREE,
|
|
138
|
+
.dsize = NULL, // We don't track profile memory usage (although it'd be cool if we did!)
|
|
139
|
+
//.dcompact = NULL, // FIXME: Add support for compaction
|
|
140
|
+
},
|
|
141
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
static VALUE _native_new(VALUE klass) {
|
|
145
|
+
struct cpu_and_wall_time_worker_state *state = ruby_xcalloc(1, sizeof(struct cpu_and_wall_time_worker_state));
|
|
146
|
+
|
|
147
|
+
state->should_run = false;
|
|
148
|
+
state->cpu_and_wall_time_collector_instance = Qnil;
|
|
149
|
+
state->failure_exception = Qnil;
|
|
150
|
+
|
|
151
|
+
return TypedData_Wrap_Struct(klass, &cpu_and_wall_time_worker_typed_data, state);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
static VALUE _native_initialize(DDTRACE_UNUSED VALUE _self, VALUE self_instance, VALUE cpu_and_wall_time_collector_instance) {
|
|
155
|
+
struct cpu_and_wall_time_worker_state *state;
|
|
156
|
+
TypedData_Get_Struct(self_instance, struct cpu_and_wall_time_worker_state, &cpu_and_wall_time_worker_typed_data, state);
|
|
157
|
+
|
|
158
|
+
state->cpu_and_wall_time_collector_instance = enforce_cpu_and_wall_time_collector_instance(cpu_and_wall_time_collector_instance);
|
|
159
|
+
|
|
160
|
+
return Qtrue;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Since our state contains references to Ruby objects, we need to tell the Ruby GC about them
|
|
164
|
+
static void cpu_and_wall_time_worker_typed_data_mark(void *state_ptr) {
|
|
165
|
+
struct cpu_and_wall_time_worker_state *state = (struct cpu_and_wall_time_worker_state *) state_ptr;
|
|
166
|
+
|
|
167
|
+
rb_gc_mark(state->cpu_and_wall_time_collector_instance);
|
|
168
|
+
rb_gc_mark(state->failure_exception);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Called in a background thread created in CpuAndWallTimeWorker#start
|
|
172
|
+
static VALUE _native_sampling_loop(DDTRACE_UNUSED VALUE _self, VALUE instance) {
|
|
173
|
+
struct cpu_and_wall_time_worker_state *state;
|
|
174
|
+
TypedData_Get_Struct(instance, struct cpu_and_wall_time_worker_state, &cpu_and_wall_time_worker_typed_data, state);
|
|
175
|
+
|
|
176
|
+
if (active_sampler_owner_thread != Qnil && is_thread_alive(active_sampler_owner_thread)) {
|
|
177
|
+
rb_raise(
|
|
178
|
+
rb_eRuntimeError,
|
|
179
|
+
"Could not start CpuAndWallTimeWorker: There's already another instance of CpuAndWallTimeWorker active in a different thread"
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// This write to a global is thread-safe BECAUSE we're still holding on to the global VM lock at this point
|
|
184
|
+
active_sampler_instance = instance;
|
|
185
|
+
active_sampler_owner_thread = rb_thread_current();
|
|
186
|
+
|
|
187
|
+
state->should_run = true;
|
|
188
|
+
|
|
189
|
+
block_sigprof_signal_handler_from_running_in_current_thread(); // We want to interrupt the thread with the global VM lock, never this one
|
|
190
|
+
|
|
191
|
+
install_sigprof_signal_handler(handle_sampling_signal);
|
|
192
|
+
|
|
193
|
+
// Release GVL, get to the actual work!
|
|
194
|
+
int exception_state;
|
|
195
|
+
rb_protect(release_gvl_and_run_sampling_trigger_loop, instance, &exception_state);
|
|
196
|
+
|
|
197
|
+
// The sample trigger loop finished (either cleanly or with an error); let's clean up
|
|
198
|
+
|
|
199
|
+
remove_sigprof_signal_handler();
|
|
200
|
+
active_sampler_instance = Qnil;
|
|
201
|
+
active_sampler_owner_thread = Qnil;
|
|
202
|
+
|
|
203
|
+
// Ensure that instance is not garbage collected while the native sampling loop is running; this is probably not needed, but just in case
|
|
204
|
+
RB_GC_GUARD(instance);
|
|
205
|
+
|
|
206
|
+
if (exception_state) rb_jump_tag(exception_state); // Re-raise any exception that happened
|
|
207
|
+
|
|
208
|
+
return Qnil;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
static VALUE _native_stop(DDTRACE_UNUSED VALUE _self, VALUE self_instance) {
|
|
212
|
+
struct cpu_and_wall_time_worker_state *state;
|
|
213
|
+
TypedData_Get_Struct(self_instance, struct cpu_and_wall_time_worker_state, &cpu_and_wall_time_worker_typed_data, state);
|
|
214
|
+
|
|
215
|
+
state->should_run = false;
|
|
216
|
+
|
|
217
|
+
return Qtrue;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
static void install_sigprof_signal_handler(void (*signal_handler_function)(int, siginfo_t *, void *)) {
|
|
221
|
+
struct sigaction existing_signal_handler_config = {.sa_sigaction = NULL};
|
|
222
|
+
struct sigaction signal_handler_config = {
|
|
223
|
+
.sa_flags = SA_RESTART | SA_SIGINFO,
|
|
224
|
+
.sa_sigaction = signal_handler_function
|
|
225
|
+
};
|
|
226
|
+
sigemptyset(&signal_handler_config.sa_mask);
|
|
227
|
+
|
|
228
|
+
if (sigaction(SIGPROF, &signal_handler_config, &existing_signal_handler_config) != 0) {
|
|
229
|
+
rb_sys_fail("Could not start CpuAndWallTimeWorker: Could not install signal handler");
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// In some corner cases (e.g. after a fork), our signal handler may still be around, and that's ok
|
|
233
|
+
if (existing_signal_handler_config.sa_sigaction == handle_sampling_signal) return;
|
|
234
|
+
|
|
235
|
+
if (existing_signal_handler_config.sa_handler != NULL || existing_signal_handler_config.sa_sigaction != NULL) {
|
|
236
|
+
// A previous signal handler already existed. Currently we don't support this situation, so let's just back out
|
|
237
|
+
// of the installation.
|
|
238
|
+
|
|
239
|
+
if (sigaction(SIGPROF, &existing_signal_handler_config, NULL) != 0) {
|
|
240
|
+
rb_sys_fail(
|
|
241
|
+
"Could not start CpuAndWallTimeWorker: Could not re-install pre-existing SIGPROF signal handler. " \
|
|
242
|
+
"This may break the component had installed it."
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
rb_raise(rb_eRuntimeError, "Could not start CpuAndWallTimeWorker: There's a pre-existing SIGPROF signal handler");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
static void remove_sigprof_signal_handler(void) {
|
|
251
|
+
struct sigaction signal_handler_config = {
|
|
252
|
+
.sa_handler = SIG_DFL, // Reset back to default
|
|
253
|
+
.sa_flags = SA_RESTART // TODO: Unclear if this is actually needed/does anything at all
|
|
254
|
+
};
|
|
255
|
+
sigemptyset(&signal_handler_config.sa_mask);
|
|
256
|
+
|
|
257
|
+
if (sigaction(SIGPROF, &signal_handler_config, NULL) != 0) rb_sys_fail("Failure while removing the signal handler");
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
static void block_sigprof_signal_handler_from_running_in_current_thread(void) {
|
|
261
|
+
sigset_t signals_to_block;
|
|
262
|
+
sigemptyset(&signals_to_block);
|
|
263
|
+
sigaddset(&signals_to_block, SIGPROF);
|
|
264
|
+
pthread_sigmask(SIG_BLOCK, &signals_to_block, NULL);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
static void handle_sampling_signal(DDTRACE_UNUSED int _signal, DDTRACE_UNUSED siginfo_t *_info, DDTRACE_UNUSED void *_ucontext) {
|
|
268
|
+
if (!ruby_thread_has_gvl_p()) {
|
|
269
|
+
return; // Not safe to enqueue a sample from this thread
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// We implicitly assume there can be no concurrent nor nested calls to handle_sampling_signal because
|
|
273
|
+
// a) we get triggered using SIGPROF, and the docs state second SIGPROF will not interrupt an existing one
|
|
274
|
+
// b) we validate we are in the thread that has the global VM lock; if a different thread gets a signal, it will return early
|
|
275
|
+
// because it will not have the global VM lock
|
|
276
|
+
// TODO: Validate that this does not impact Ractors
|
|
277
|
+
|
|
278
|
+
// Note: rb_postponed_job_register_one ensures that if there's a previous sample_from_postponed_job queued for execution
|
|
279
|
+
// then we will not queue a second one. It does this by doing a linear scan on the existing jobs; in the future we
|
|
280
|
+
// may want to implement that check ourselves.
|
|
281
|
+
|
|
282
|
+
// TODO: Do something with result (potentially update tracking counters?)
|
|
283
|
+
/*int result =*/ rb_postponed_job_register_one(0, sample_from_postponed_job, NULL);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// The actual sampling trigger loop always runs **without** the global vm lock.
|
|
287
|
+
static void *run_sampling_trigger_loop(void *state_ptr) {
|
|
288
|
+
struct cpu_and_wall_time_worker_state *state = (struct cpu_and_wall_time_worker_state *) state_ptr;
|
|
289
|
+
|
|
290
|
+
struct timespec time_between_signals = {.tv_nsec = 10 * 1000 * 1000 /* 10ms */};
|
|
291
|
+
|
|
292
|
+
while (state->should_run) {
|
|
293
|
+
// TODO: This is still a placeholder for a more complex mechanism. In particular:
|
|
294
|
+
// * We want to signal a particular thread or threads, not the process in general
|
|
295
|
+
// * We want to track if a signal landed on the thread holding the global VM lock and do something about it
|
|
296
|
+
// * We want to do more than having a fixed sampling rate
|
|
297
|
+
|
|
298
|
+
kill(getpid(), SIGPROF);
|
|
299
|
+
nanosleep(&time_between_signals, NULL);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return NULL; // Unused
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// This is called by the Ruby VM when it wants to shut down the background thread
|
|
306
|
+
static void interrupt_sampling_trigger_loop(void *state_ptr) {
|
|
307
|
+
struct cpu_and_wall_time_worker_state *state = (struct cpu_and_wall_time_worker_state *) state_ptr;
|
|
308
|
+
|
|
309
|
+
state->should_run = false;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
static void sample_from_postponed_job(DDTRACE_UNUSED void *_unused) {
|
|
313
|
+
VALUE instance = active_sampler_instance; // Read from global variable
|
|
314
|
+
|
|
315
|
+
// This can potentially happen if the CpuAndWallTimeWorker was stopped while the postponed job was waiting to be executed; nothing to do
|
|
316
|
+
if (instance == Qnil) return;
|
|
317
|
+
|
|
318
|
+
struct cpu_and_wall_time_worker_state *state;
|
|
319
|
+
TypedData_Get_Struct(instance, struct cpu_and_wall_time_worker_state, &cpu_and_wall_time_worker_typed_data, state);
|
|
320
|
+
|
|
321
|
+
// Trigger sampling using the Collectors::CpuAndWallTime; rescue against any exceptions that happen during sampling
|
|
322
|
+
VALUE (*function_to_call_safely)(VALUE) = cpu_and_wall_time_collector_sample;
|
|
323
|
+
VALUE function_to_call_safely_arg = state->cpu_and_wall_time_collector_instance;
|
|
324
|
+
VALUE (*exception_handler_function)(VALUE, VALUE) = handle_sampling_failure;
|
|
325
|
+
VALUE exception_handler_function_arg = instance;
|
|
326
|
+
rb_rescue2(
|
|
327
|
+
function_to_call_safely,
|
|
328
|
+
function_to_call_safely_arg,
|
|
329
|
+
exception_handler_function,
|
|
330
|
+
exception_handler_function_arg,
|
|
331
|
+
rb_eException, // rb_eException is the base class of all Ruby exceptions
|
|
332
|
+
0 // Required by API to be the last argument
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
static VALUE handle_sampling_failure(VALUE self_instance, VALUE exception) {
|
|
337
|
+
struct cpu_and_wall_time_worker_state *state;
|
|
338
|
+
TypedData_Get_Struct(self_instance, struct cpu_and_wall_time_worker_state, &cpu_and_wall_time_worker_typed_data, state);
|
|
339
|
+
|
|
340
|
+
state->should_run = false;
|
|
341
|
+
state->failure_exception = exception;
|
|
342
|
+
|
|
343
|
+
return Qnil;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
static VALUE _native_current_sigprof_signal_handler(DDTRACE_UNUSED VALUE self) {
|
|
347
|
+
struct sigaction existing_signal_handler_config = {.sa_sigaction = NULL};
|
|
348
|
+
if (sigaction(SIGPROF, NULL, &existing_signal_handler_config) != 0) {
|
|
349
|
+
rb_sys_fail("Failed to probe existing handler");
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (existing_signal_handler_config.sa_sigaction == handle_sampling_signal) {
|
|
353
|
+
return ID2SYM(rb_intern("profiling"));
|
|
354
|
+
} else if (existing_signal_handler_config.sa_sigaction != NULL) {
|
|
355
|
+
return ID2SYM(rb_intern("other"));
|
|
356
|
+
} else {
|
|
357
|
+
return Qnil;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
static VALUE release_gvl_and_run_sampling_trigger_loop(VALUE instance) {
|
|
362
|
+
struct cpu_and_wall_time_worker_state *state;
|
|
363
|
+
TypedData_Get_Struct(instance, struct cpu_and_wall_time_worker_state, &cpu_and_wall_time_worker_typed_data, state);
|
|
364
|
+
|
|
365
|
+
rb_thread_call_without_gvl(run_sampling_trigger_loop, state, interrupt_sampling_trigger_loop, state);
|
|
366
|
+
|
|
367
|
+
// If we stopped sampling due to an exception, re-raise it (now in the worker thread)
|
|
368
|
+
if (state->failure_exception != Qnil) rb_exc_raise(state->failure_exception);
|
|
369
|
+
|
|
370
|
+
return Qnil;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
static VALUE _native_is_running(DDTRACE_UNUSED VALUE self, VALUE instance) {
|
|
374
|
+
return \
|
|
375
|
+
(active_sampler_owner_thread != Qnil && is_thread_alive(active_sampler_owner_thread) && active_sampler_instance == instance) ?
|
|
376
|
+
Qtrue : Qfalse;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
static void testing_signal_handler(DDTRACE_UNUSED int _signal, DDTRACE_UNUSED siginfo_t *_info, DDTRACE_UNUSED void *_ucontext) {
|
|
380
|
+
/* Does nothing on purpose */
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
static VALUE _native_install_testing_signal_handler(DDTRACE_UNUSED VALUE self) {
|
|
384
|
+
install_sigprof_signal_handler(testing_signal_handler);
|
|
385
|
+
return Qtrue;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
static VALUE _native_remove_testing_signal_handler(DDTRACE_UNUSED VALUE self) {
|
|
389
|
+
remove_sigprof_signal_handler();
|
|
390
|
+
return Qtrue;
|
|
391
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#include <ruby.h>
|
|
2
2
|
#include <ruby/debug.h>
|
|
3
3
|
#include "extconf.h"
|
|
4
|
-
#include "
|
|
4
|
+
#include "helpers.h"
|
|
5
|
+
#include "libdatadog_helpers.h"
|
|
6
|
+
#include "ruby_helpers.h"
|
|
5
7
|
#include "private_vm_api_access.h"
|
|
6
8
|
#include "stack_recorder.h"
|
|
7
9
|
#include "collectors_stack.h"
|
|
@@ -31,8 +33,10 @@ static void record_placeholder_stack_in_native_code(VALUE recorder_instance, ddp
|
|
|
31
33
|
void collectors_stack_init(VALUE profiling_module) {
|
|
32
34
|
VALUE collectors_module = rb_define_module_under(profiling_module, "Collectors");
|
|
33
35
|
VALUE collectors_stack_class = rb_define_class_under(collectors_module, "Stack", rb_cObject);
|
|
36
|
+
// Hosts methods used for testing the native code using RSpec
|
|
37
|
+
VALUE testing_module = rb_define_module_under(collectors_stack_class, "Testing");
|
|
34
38
|
|
|
35
|
-
rb_define_singleton_method(
|
|
39
|
+
rb_define_singleton_method(testing_module, "_native_sample", _native_sample, 5);
|
|
36
40
|
|
|
37
41
|
missing_string = rb_str_new2("");
|
|
38
42
|
rb_global_variable(&missing_string);
|
|
@@ -40,9 +44,9 @@ void collectors_stack_init(VALUE profiling_module) {
|
|
|
40
44
|
|
|
41
45
|
// This method exists only to enable testing Datadog::Profiling::Collectors::Stack behavior using RSpec.
|
|
42
46
|
// It SHOULD NOT be used for other purposes.
|
|
43
|
-
static VALUE _native_sample(VALUE
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
static VALUE _native_sample(DDTRACE_UNUSED VALUE _self, VALUE thread, VALUE recorder_instance, VALUE metric_values_hash, VALUE labels_array, VALUE max_frames) {
|
|
48
|
+
ENFORCE_TYPE(metric_values_hash, T_HASH);
|
|
49
|
+
ENFORCE_TYPE(labels_array, T_ARRAY);
|
|
46
50
|
|
|
47
51
|
if (RHASH_SIZE(metric_values_hash) != ENABLED_VALUE_TYPES_COUNT) {
|
|
48
52
|
rb_raise(
|
|
@@ -137,8 +141,8 @@ void sample_thread(VALUE thread, sampling_buffer* buffer, VALUE recorder_instanc
|
|
|
137
141
|
// **IMPORTANT**: Be very careful when calling any `rb_profile_frame_...` API with a non-Ruby frame, as legacy
|
|
138
142
|
// Rubies may assume that what's in a buffer will lead to a Ruby frame.
|
|
139
143
|
//
|
|
140
|
-
// In particular for Ruby 2.2
|
|
141
|
-
// rb_profile_frames for Ruby 2.2
|
|
144
|
+
// In particular for Ruby 2.2 the buffer contains a Ruby string (see the notes on our custom
|
|
145
|
+
// rb_profile_frames for Ruby 2.2) and CALLING **ANY** OF THOSE APIs ON IT WILL CAUSE INSTANT VM CRASHES
|
|
142
146
|
|
|
143
147
|
#ifndef USE_LEGACY_RB_PROFILE_FRAMES // Modern Rubies
|
|
144
148
|
name = ddtrace_rb_profile_frame_method_name(buffer->stack_buffer[i]);
|
|
@@ -42,7 +42,8 @@ unless Datadog::Profiling::NativeExtensionHelpers::Supported.supported?
|
|
|
42
42
|
skip_building_extension!(Datadog::Profiling::NativeExtensionHelpers::Supported.unsupported_reason)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
$stderr.puts(
|
|
45
|
+
$stderr.puts(
|
|
46
|
+
%(
|
|
46
47
|
+------------------------------------------------------------------------------+
|
|
47
48
|
| ** Preparing to build the ddtrace profiling native extension... ** |
|
|
48
49
|
| |
|
|
@@ -59,7 +60,8 @@ $stderr.puts(%(
|
|
|
59
60
|
| Thanks for using ddtrace! You rock! |
|
|
60
61
|
+------------------------------------------------------------------------------+
|
|
61
62
|
|
|
62
|
-
)
|
|
63
|
+
)
|
|
64
|
+
)
|
|
63
65
|
|
|
64
66
|
# NOTE: we MUST NOT require 'mkmf' before we check the #skip_building_extension? because the require triggers checks
|
|
65
67
|
# that may fail on an environment not properly setup for building Ruby extensions.
|
|
@@ -91,6 +93,9 @@ add_compiler_flag '-Wno-declaration-after-statement'
|
|
|
91
93
|
# cause a segfault later. Let's ensure that never happens.
|
|
92
94
|
add_compiler_flag '-Werror-implicit-function-declaration'
|
|
93
95
|
|
|
96
|
+
# Warn on unused parameters to functions. Use `DDTRACE_UNUSED` to mark things as known-to-not-be-used.
|
|
97
|
+
add_compiler_flag '-Wunused-parameter'
|
|
98
|
+
|
|
94
99
|
# The native extension is not intended to expose any symbols/functions for other native libraries to use;
|
|
95
100
|
# the sole exception being `Init_ddtrace_profiling_native_extension` which needs to be visible for Ruby to call it when
|
|
96
101
|
# it `dlopen`s the library.
|
|
@@ -99,13 +104,17 @@ add_compiler_flag '-Werror-implicit-function-declaration'
|
|
|
99
104
|
# For more details see https://gcc.gnu.org/wiki/Visibility
|
|
100
105
|
add_compiler_flag '-fvisibility=hidden'
|
|
101
106
|
|
|
107
|
+
# Enable all other compiler warnings
|
|
108
|
+
add_compiler_flag '-Wall'
|
|
109
|
+
add_compiler_flag '-Wextra'
|
|
110
|
+
|
|
102
111
|
if RUBY_PLATFORM.include?('linux')
|
|
103
112
|
# Supposedly, the correct way to do this is
|
|
104
113
|
# ```
|
|
105
114
|
# have_library 'pthread'
|
|
106
115
|
# have_func 'pthread_getcpuclockid'
|
|
107
116
|
# ```
|
|
108
|
-
# but it broke the build on Windows and on older Ruby versions (2.
|
|
117
|
+
# but it broke the build on Windows and on older Ruby versions (2.2)
|
|
109
118
|
# so instead we just assume that we have the function we need on Linux, and nowhere else
|
|
110
119
|
$defs << '-DHAVE_PTHREAD_GETCPUCLOCKID'
|
|
111
120
|
end
|
|
@@ -133,13 +142,14 @@ if RUBY_VERSION < '2.3'
|
|
|
133
142
|
$defs << '-DNO_RB_TIME_TIMESPEC_NEW'
|
|
134
143
|
# ...the VM changed enough that we need an alternative legacy rb_profile_frames
|
|
135
144
|
$defs << '-DUSE_LEGACY_RB_PROFILE_FRAMES'
|
|
145
|
+
# ... you couldn't name threads
|
|
146
|
+
$defs << '-DNO_THREAD_NAMES'
|
|
147
|
+
# ...the ruby_thread_has_gvl_p function was not exposed to users outside of the VM
|
|
148
|
+
$defs << '-DNO_THREAD_HAS_GVL'
|
|
136
149
|
end
|
|
137
150
|
|
|
138
|
-
#
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
# If we got here, libddprof is available and loaded
|
|
142
|
-
ENV['PKG_CONFIG_PATH'] = "#{ENV['PKG_CONFIG_PATH']}:#{Libddprof.pkgconfig_folder}"
|
|
151
|
+
# If we got here, libdatadog is available and loaded
|
|
152
|
+
ENV['PKG_CONFIG_PATH'] = "#{ENV['PKG_CONFIG_PATH']}:#{Libdatadog.pkgconfig_folder}"
|
|
143
153
|
Logging.message(" [ddtrace] PKG_CONFIG_PATH set to #{ENV['PKG_CONFIG_PATH'].inspect}\n")
|
|
144
154
|
|
|
145
155
|
unless pkg_config('ddprof_ffi_with_rpath')
|
|
@@ -148,19 +158,23 @@ unless pkg_config('ddprof_ffi_with_rpath')
|
|
|
148
158
|
Datadog::Profiling::NativeExtensionHelpers::Supported::PKG_CONFIG_IS_MISSING
|
|
149
159
|
else
|
|
150
160
|
# Less specific error message
|
|
151
|
-
Datadog::Profiling::NativeExtensionHelpers::Supported::
|
|
161
|
+
Datadog::Profiling::NativeExtensionHelpers::Supported::FAILED_TO_CONFIGURE_LIBDATADOG
|
|
152
162
|
end
|
|
153
163
|
)
|
|
154
164
|
end
|
|
155
165
|
|
|
156
|
-
# See comments on the helper method being used for why we need to additionally set this
|
|
166
|
+
# See comments on the helper method being used for why we need to additionally set this.
|
|
157
167
|
# The extremely excessive escaping around ORIGIN below seems to be correct and was determined after a lot of
|
|
158
168
|
# experimentation. We need to get these special characters across a lot of tools untouched...
|
|
159
169
|
$LDFLAGS += \
|
|
160
170
|
' -Wl,-rpath,$$$\\\\{ORIGIN\\}/' \
|
|
161
|
-
"#{Datadog::Profiling::NativeExtensionHelpers.
|
|
171
|
+
"#{Datadog::Profiling::NativeExtensionHelpers.libdatadog_folder_relative_to_native_lib_folder}"
|
|
162
172
|
Logging.message(" [ddtrace] After pkg-config $LDFLAGS were set to: #{$LDFLAGS.inspect}\n")
|
|
163
173
|
|
|
174
|
+
Logging.message(" [ddtrace] Using compiler:\n")
|
|
175
|
+
xsystem("#{CONFIG['CC']} --version")
|
|
176
|
+
Logging.message(" [ddtrace] End of compiler information\n")
|
|
177
|
+
|
|
164
178
|
# Tag the native extension library with the Ruby version and Ruby platform.
|
|
165
179
|
# This makes it easier for development (avoids "oops I forgot to rebuild when I switched my Ruby") and ensures that
|
|
166
180
|
# the wrong library is never loaded.
|
|
@@ -194,13 +208,6 @@ else
|
|
|
194
208
|
# This gem ships source code copies of these VM headers for the different Ruby VM versions;
|
|
195
209
|
# see https://github.com/ruby-debug/debase-ruby_core_source for details
|
|
196
210
|
|
|
197
|
-
thread_native_for_ruby_2_1 = proc { true }
|
|
198
|
-
if RUBY_VERSION < '2.2'
|
|
199
|
-
# This header became public in Ruby 2.2, but we need to pull it from the private headers folder for 2.1
|
|
200
|
-
thread_native_for_ruby_2_1 = proc { have_header('thread_native.h') }
|
|
201
|
-
$defs << '-DRUBY_2_1_WORKAROUND'
|
|
202
|
-
end
|
|
203
|
-
|
|
204
211
|
create_header
|
|
205
212
|
|
|
206
213
|
require 'debase/ruby_core_source'
|
|
@@ -208,7 +215,7 @@ else
|
|
|
208
215
|
|
|
209
216
|
Debase::RubyCoreSource
|
|
210
217
|
.create_makefile_with_core(
|
|
211
|
-
proc { have_header('vm_core.h') && have_header('iseq.h')
|
|
218
|
+
proc { have_header('vm_core.h') && have_header('iseq.h') },
|
|
212
219
|
EXTENSION_NAME,
|
|
213
220
|
)
|
|
214
221
|
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
// Used to mark symbols to be exported to the outside of the extension.
|
|
4
|
+
// Consider very carefully before tagging a function with this.
|
|
5
|
+
#define DDTRACE_EXPORT __attribute__ ((visibility ("default")))
|
|
6
|
+
|
|
7
|
+
// Used to mark function arguments that are deliberately left unused
|
|
8
|
+
#ifdef __GNUC__
|
|
9
|
+
#define DDTRACE_UNUSED __attribute__((unused))
|
|
10
|
+
#else
|
|
11
|
+
#define DDTRACE_UNUSED
|
|
12
|
+
#endif
|