ddtrace 1.5.2 → 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +56 -2
  3. data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +9 -2
  4. data/ext/ddtrace_profiling_loader/extconf.rb +17 -0
  5. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +38 -2
  6. data/ext/ddtrace_profiling_native_extension/clock_id.h +1 -0
  7. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +1 -0
  8. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +517 -42
  9. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.h +3 -0
  10. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +208 -30
  11. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +156 -46
  12. data/ext/ddtrace_profiling_native_extension/collectors_stack.h +11 -2
  13. data/ext/ddtrace_profiling_native_extension/extconf.rb +11 -1
  14. data/ext/ddtrace_profiling_native_extension/http_transport.c +83 -64
  15. data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +4 -4
  16. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +3 -2
  17. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +59 -0
  18. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +3 -0
  19. data/ext/ddtrace_profiling_native_extension/profiling.c +10 -0
  20. data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +0 -1
  21. data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +4 -2
  22. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +45 -29
  23. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +7 -7
  24. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +4 -0
  25. data/lib/datadog/appsec/event.rb +6 -0
  26. data/lib/datadog/core/configuration/components.rb +20 -14
  27. data/lib/datadog/core/configuration/settings.rb +42 -4
  28. data/lib/datadog/core/diagnostics/environment_logger.rb +5 -1
  29. data/lib/datadog/core/utils/compression.rb +5 -1
  30. data/lib/datadog/core.rb +0 -54
  31. data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +12 -2
  32. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +5 -3
  33. data/lib/datadog/profiling/exporter.rb +2 -4
  34. data/lib/datadog/profiling/http_transport.rb +1 -1
  35. data/lib/datadog/tracing/configuration/ext.rb +1 -0
  36. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +2 -0
  37. data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
  38. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +4 -0
  39. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +2 -0
  40. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +3 -0
  41. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +2 -0
  42. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +2 -0
  43. data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -0
  44. data/lib/datadog/tracing/contrib/ext.rb +6 -0
  45. data/lib/datadog/tracing/contrib/faraday/middleware.rb +2 -0
  46. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +5 -0
  47. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +7 -1
  48. data/lib/datadog/tracing/contrib/grpc/ext.rb +2 -0
  49. data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +47 -0
  50. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +22 -0
  51. data/lib/datadog/tracing/contrib/hanami/ext.rb +24 -0
  52. data/lib/datadog/tracing/contrib/hanami/integration.rb +44 -0
  53. data/lib/datadog/tracing/contrib/hanami/patcher.rb +33 -0
  54. data/lib/datadog/tracing/contrib/hanami/plugin.rb +23 -0
  55. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +41 -0
  56. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +44 -0
  57. data/lib/datadog/tracing/contrib/http/instrumentation.rb +2 -0
  58. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +2 -0
  59. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +2 -0
  60. data/lib/datadog/tracing/contrib/mongodb/ext.rb +7 -0
  61. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +4 -0
  62. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +12 -0
  63. data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
  64. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +16 -0
  65. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +12 -0
  66. data/lib/datadog/tracing/contrib/pg/ext.rb +2 -1
  67. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +34 -18
  68. data/lib/datadog/tracing/contrib/propagation/sql_comment/comment.rb +43 -0
  69. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +32 -0
  70. data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +28 -0
  71. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +49 -0
  72. data/lib/datadog/tracing/contrib/rack/middlewares.rb +11 -5
  73. data/lib/datadog/tracing/contrib/redis/ext.rb +2 -0
  74. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +4 -2
  75. data/lib/datadog/tracing/contrib/redis/integration.rb +2 -1
  76. data/lib/datadog/tracing/contrib/redis/patcher.rb +40 -0
  77. data/lib/datadog/tracing/contrib/redis/tags.rb +5 -0
  78. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +2 -0
  79. data/lib/datadog/tracing/contrib/sinatra/env.rb +12 -23
  80. data/lib/datadog/tracing/contrib/sinatra/ext.rb +7 -3
  81. data/lib/datadog/tracing/contrib/sinatra/patcher.rb +2 -2
  82. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +8 -80
  83. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +14 -9
  84. data/lib/datadog/tracing/contrib.rb +1 -0
  85. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +84 -0
  86. data/lib/datadog/tracing/distributed/headers/datadog.rb +122 -30
  87. data/lib/datadog/tracing/distributed/headers/ext.rb +2 -0
  88. data/lib/datadog/tracing/flush.rb +1 -1
  89. data/lib/datadog/tracing/metadata/ext.rb +8 -0
  90. data/lib/datadog/tracing/propagation/http.rb +9 -1
  91. data/lib/datadog/tracing/sampling/ext.rb +31 -0
  92. data/lib/datadog/tracing/sampling/priority_sampler.rb +46 -4
  93. data/lib/datadog/tracing/sampling/rate_by_key_sampler.rb +8 -9
  94. data/lib/datadog/tracing/sampling/rate_by_service_sampler.rb +29 -5
  95. data/lib/datadog/tracing/sampling/rate_sampler.rb +10 -3
  96. data/lib/datadog/tracing/sampling/rule_sampler.rb +4 -3
  97. data/lib/datadog/tracing/sampling/span/ext.rb +0 -4
  98. data/lib/datadog/tracing/sampling/span/rule.rb +1 -1
  99. data/lib/datadog/tracing/sampling/span/sampler.rb +14 -3
  100. data/lib/datadog/tracing/trace_digest.rb +3 -0
  101. data/lib/datadog/tracing/trace_operation.rb +10 -0
  102. data/lib/datadog/tracing/trace_segment.rb +6 -0
  103. data/lib/datadog/tracing/tracer.rb +3 -1
  104. data/lib/datadog/tracing/writer.rb +7 -0
  105. data/lib/ddtrace/transport/trace_formatter.rb +7 -0
  106. data/lib/ddtrace/transport/traces.rb +1 -1
  107. data/lib/ddtrace/version.rb +2 -2
  108. metadata +18 -14
  109. data/lib/datadog/profiling/old_ext.rb +0 -42
  110. data/lib/datadog/profiling/transport/http/api/endpoint.rb +0 -85
  111. data/lib/datadog/profiling/transport/http/api/instance.rb +0 -38
  112. data/lib/datadog/profiling/transport/http/api/spec.rb +0 -42
  113. data/lib/datadog/profiling/transport/http/api.rb +0 -45
  114. data/lib/datadog/profiling/transport/http/builder.rb +0 -30
  115. data/lib/datadog/profiling/transport/http/client.rb +0 -37
  116. data/lib/datadog/profiling/transport/http/response.rb +0 -21
  117. data/lib/datadog/profiling/transport/http.rb +0 -118
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5417d6aa2797b38bfe55167afa723cb2479bd3b7fae3ad3ee16020844084a48e
4
- data.tar.gz: 3c63a3c9dcce6c180349814da8113ba8e9b6b3334f2a4ab13ceeef4cc006c70c
3
+ metadata.gz: 7a13232b0a3e34d8c05f4e9cd14083d3da7899e4cd4a8a52a95495193dce81b4
4
+ data.tar.gz: '0975d24547f318e657422c35ef54f8f68cff797436594d30514d163b55170220'
5
5
  SHA512:
6
- metadata.gz: e82cadb7da0c30c4f22791fab2f1ef356cf33378756673a74fa2dbcf447a25530421f86d809a86dcab5ccd31d332bca5759a589e9dfdaebc47d3b3d8f201c662
7
- data.tar.gz: b36eafe691e5808bc179e693549e7aa7747d400502d0d21f500dac0129c726a4b433498c6b41896fd3351a382ddede220540d8c0a14b12bf240d320d037ae786
6
+ metadata.gz: da8917c06511999a28152037efa177fceba67d0329534bc8a462d17ffb151bfad0f360318262be095fc73ce42990051e6856b2cc3663317091b552d76730116c
7
+ data.tar.gz: 44a8062936ae2f20fdca4d524d6390825b87092d58ebb934d2e4b715f442b595be020752b3a2c0fd432d4dc3901ad611725adf4d70139c095d78e7b2b127fdd1
data/CHANGELOG.md CHANGED
@@ -2,6 +2,45 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.6.1] - 2022-11-16
6
+
7
+ ### Changed
8
+
9
+ * Limit `redis` version support to less than 5
10
+
11
+ ### Fixed
12
+
13
+ * [redis]: Fix frozen input for `Redis.new(...)`
14
+
15
+ ## [1.6.0] - 2022-11-15
16
+
17
+ ### Added
18
+
19
+ * Trace level tags propagation in distributed tracing ([#2260][])
20
+ * [hanami]: Hanami 1.x instrumentation ([#2230][])
21
+ * [pg, mysql2]: option `comment_propagation` for SQL comment propagation, default is `disabled` ([#2339][])([#2324][])
22
+
23
+ ### Changed
24
+
25
+ * [rack, sinatra]: Squash nested spans and improve patching mechanism.<br> No need to `register Datadog::Tracing::Contrib::Sinatra::Tracer`([#2217][])
26
+ * [rails, rack]: Fix Non-GET request method with rails exception controller ([#2317][])
27
+ * Upgrade to libdatadog 0.9.0.1.0 ([#2302][])
28
+ * Remove legacy profiling transport ([#2062][])
29
+
30
+ ### Fixed
31
+
32
+ * [redis]: Fix redis instance configuration, not on `client` ([#2363][])
33
+ ```
34
+ # Change your code from
35
+ Datadog.configure_onto(redis.client, service_name: '...')
36
+ # to
37
+ Datadog.configure_onto(redis, service_name: '...')
38
+ ```
39
+ * Allow `DD_TAGS` values to have the colon character ([#2292][])
40
+ * Ensure that `TraceSegment` can be reported correctly when they are dropped ([#2335][])
41
+ * Docs: Fixes upgrade guide on configure_onto ([#2307][])
42
+ * Fix environment logger with IO transport ([#2313][])
43
+
5
44
  ## [1.5.2] - 2022-10-27
6
45
 
7
46
  ### Deprecation notice
@@ -2159,7 +2198,9 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
2159
2198
 
2160
2199
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
2161
2200
 
2162
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.5.2...master
2201
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v1.6.1...master
2202
+ [1.6.1]: https://github.com/DataDog/dd-trace-rb/compare/v1.6.0...v1.6.1
2203
+ [1.6.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.5.2...v1.6.0
2163
2204
  [1.5.2]: https://github.com/DataDog/dd-trace-rb/compare/v1.5.1...v1.5.2
2164
2205
  [1.5.1]: https://github.com/DataDog/dd-trace-rb/compare/v1.5.0...v1.5.1
2165
2206
  [1.5.0]: https://github.com/DataDog/dd-trace-rb/compare/v1.4.2...v1.5.0
@@ -3018,6 +3059,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3018
3059
  [#2054]: https://github.com/DataDog/dd-trace-rb/issues/2054
3019
3060
  [#2059]: https://github.com/DataDog/dd-trace-rb/issues/2059
3020
3061
  [#2061]: https://github.com/DataDog/dd-trace-rb/issues/2061
3062
+ [#2062]: https://github.com/DataDog/dd-trace-rb/issues/2062
3021
3063
  [#2066]: https://github.com/DataDog/dd-trace-rb/issues/2066
3022
3064
  [#2069]: https://github.com/DataDog/dd-trace-rb/issues/2069
3023
3065
  [#2070]: https://github.com/DataDog/dd-trace-rb/issues/2070
@@ -3048,29 +3090,41 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3048
3090
  [#2191]: https://github.com/DataDog/dd-trace-rb/issues/2191
3049
3091
  [#2200]: https://github.com/DataDog/dd-trace-rb/issues/2200
3050
3092
  [#2201]: https://github.com/DataDog/dd-trace-rb/issues/2201
3093
+ [#2217]: https://github.com/DataDog/dd-trace-rb/issues/2217
3051
3094
  [#2219]: https://github.com/DataDog/dd-trace-rb/issues/2219
3052
3095
  [#2229]: https://github.com/DataDog/dd-trace-rb/issues/2229
3096
+ [#2230]: https://github.com/DataDog/dd-trace-rb/issues/2230
3053
3097
  [#2248]: https://github.com/DataDog/dd-trace-rb/issues/2248
3054
3098
  [#2250]: https://github.com/DataDog/dd-trace-rb/issues/2250
3055
3099
  [#2252]: https://github.com/DataDog/dd-trace-rb/issues/2252
3056
3100
  [#2257]: https://github.com/DataDog/dd-trace-rb/issues/2257
3057
3101
  [#2258]: https://github.com/DataDog/dd-trace-rb/issues/2258
3102
+ [#2260]: https://github.com/DataDog/dd-trace-rb/issues/2260
3058
3103
  [#2265]: https://github.com/DataDog/dd-trace-rb/issues/2265
3059
3104
  [#2267]: https://github.com/DataDog/dd-trace-rb/issues/2267
3060
3105
  [#2279]: https://github.com/DataDog/dd-trace-rb/issues/2279
3061
3106
  [#2283]: https://github.com/DataDog/dd-trace-rb/issues/2283
3062
3107
  [#2289]: https://github.com/DataDog/dd-trace-rb/issues/2289
3108
+ [#2292]: https://github.com/DataDog/dd-trace-rb/issues/2292
3063
3109
  [#2293]: https://github.com/DataDog/dd-trace-rb/issues/2293
3064
3110
  [#2296]: https://github.com/DataDog/dd-trace-rb/issues/2296
3111
+ [#2302]: https://github.com/DataDog/dd-trace-rb/issues/2302
3065
3112
  [#2306]: https://github.com/DataDog/dd-trace-rb/issues/2306
3113
+ [#2307]: https://github.com/DataDog/dd-trace-rb/issues/2307
3066
3114
  [#2310]: https://github.com/DataDog/dd-trace-rb/issues/2310
3067
3115
  [#2311]: https://github.com/DataDog/dd-trace-rb/issues/2311
3116
+ [#2313]: https://github.com/DataDog/dd-trace-rb/issues/2313
3117
+ [#2317]: https://github.com/DataDog/dd-trace-rb/issues/2317
3068
3118
  [#2318]: https://github.com/DataDog/dd-trace-rb/issues/2318
3069
3119
  [#2319]: https://github.com/DataDog/dd-trace-rb/issues/2319
3070
3120
  [#2321]: https://github.com/DataDog/dd-trace-rb/issues/2321
3121
+ [#2324]: https://github.com/DataDog/dd-trace-rb/issues/2324
3071
3122
  [#2328]: https://github.com/DataDog/dd-trace-rb/issues/2328
3072
3123
  [#2330]: https://github.com/DataDog/dd-trace-rb/issues/2330
3073
3124
  [#2331]: https://github.com/DataDog/dd-trace-rb/issues/2331
3125
+ [#2335]: https://github.com/DataDog/dd-trace-rb/issues/2335
3126
+ [#2339]: https://github.com/DataDog/dd-trace-rb/issues/2339
3127
+ [#2363]: https://github.com/DataDog/dd-trace-rb/issues/2363
3074
3128
  [@AdrianLC]: https://github.com/AdrianLC
3075
3129
  [@Azure7111]: https://github.com/Azure7111
3076
3130
  [@BabyGroot]: https://github.com/BabyGroot
@@ -3214,4 +3268,4 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3214
3268
  [@y-yagi]: https://github.com/y-yagi
3215
3269
  [@yujideveloper]: https://github.com/yujideveloper
3216
3270
  [@yukimurasawa]: https://github.com/yukimurasawa
3217
- [@zachmccormick]: https://github.com/zachmccormick
3271
+ [@zachmccormick]: https://github.com/zachmccormick
@@ -29,10 +29,17 @@
29
29
  #define RTLD_DEEPBIND 0
30
30
  #endif
31
31
 
32
+ // Used to mark function arguments that are deliberately left unused
33
+ #ifdef __GNUC__
34
+ #define DDTRACE_UNUSED __attribute__((unused))
35
+ #else
36
+ #define DDTRACE_UNUSED
37
+ #endif
38
+
32
39
  static VALUE ok_symbol = Qnil; // :ok in Ruby
33
40
  static VALUE error_symbol = Qnil; // :error in Ruby
34
41
 
35
- static VALUE _native_load(VALUE self, VALUE ruby_path, VALUE ruby_init_name);
42
+ static VALUE _native_load(DDTRACE_UNUSED VALUE self, VALUE ruby_path, VALUE ruby_init_name);
36
43
  static bool failed_to_load(void *handle, VALUE *failure_details);
37
44
  static bool incompatible_library(void *handle, VALUE *failure_details);
38
45
  static bool failed_to_initialize(void *handle, char *init_name, VALUE *failure_details);
@@ -51,7 +58,7 @@ void DDTRACE_EXPORT Init_ddtrace_profiling_loader(void) {
51
58
  error_symbol = ID2SYM(rb_intern_const("error"));
52
59
  }
53
60
 
54
- static VALUE _native_load(VALUE self, VALUE ruby_path, VALUE ruby_init_name) {
61
+ static VALUE _native_load(DDTRACE_UNUSED VALUE self, VALUE ruby_path, VALUE ruby_init_name) {
55
62
  Check_Type(ruby_path, T_STRING);
56
63
  Check_Type(ruby_init_name, T_STRING);
57
64
 
@@ -24,6 +24,16 @@ def add_compiler_flag(flag)
24
24
  end
25
25
  end
26
26
 
27
+ # Because we can't control what compiler versions our customers use, shipping with -Werror by default is a no-go.
28
+ # But we can enable it in CI, so that we quickly spot any new warnings that just got introduced.
29
+ add_compiler_flag '-Werror' if ENV['CI'] == 'true'
30
+
31
+ # Older gcc releases may not default to C99 and we need to ask for this. This is also used:
32
+ # * by upstream Ruby -- search for gnu99 in the codebase
33
+ # * by msgpack, another ddtrace dependency
34
+ # (https://github.com/msgpack/msgpack-ruby/blob/18ce08f6d612fe973843c366ac9a0b74c4e50599/ext/msgpack/extconf.rb#L8)
35
+ add_compiler_flag '-std=gnu99'
36
+
27
37
  # Gets really noisy when we include the MJIT header, let's omit it
28
38
  add_compiler_flag '-Wno-unused-function'
29
39
 
@@ -34,6 +44,9 @@ add_compiler_flag '-Wno-declaration-after-statement'
34
44
  # cause a segfault later. Let's ensure that never happens.
35
45
  add_compiler_flag '-Werror-implicit-function-declaration'
36
46
 
47
+ # Warn on unused parameters to functions. Use `DDTRACE_UNUSED` to mark things as known-to-not-be-used.
48
+ add_compiler_flag '-Wunused-parameter'
49
+
37
50
  # The native extension is not intended to expose any symbols/functions for other native libraries to use;
38
51
  # the sole exception being `Init_ddtrace_profiling_loader` which needs to be visible for Ruby to call it when
39
52
  # it `dlopen`s the library.
@@ -42,6 +55,10 @@ add_compiler_flag '-Werror-implicit-function-declaration'
42
55
  # For more details see https://gcc.gnu.org/wiki/Visibility
43
56
  add_compiler_flag '-fvisibility=hidden'
44
57
 
58
+ # Enable all other compiler warnings
59
+ add_compiler_flag '-Wall'
60
+ add_compiler_flag '-Wextra'
61
+
45
62
  # Tag the native extension library with the Ruby version and Ruby platform.
46
63
  # This makes it easier for development (avoids "oops I forgot to rebuild when I switched my Ruby") and ensures that
47
64
  # the wrong library is never loaded.
@@ -1,6 +1,7 @@
1
1
  # Profiling Native Extension Design
2
2
 
3
3
  The profiling native extension is used to:
4
+
4
5
  1. Implement features which are expensive (in terms of resources) or otherwise impossible to implement using Ruby code.
5
6
  2. Bridge between Ruby-specific profiling features and [`libdatadog`](https://github.com/DataDog/libdatadog), a Rust-based
6
7
  library with common profiling functionality.
@@ -20,8 +21,8 @@ and disabling the extension will disable profiling.
20
21
 
21
22
  ## Who is this page for?
22
23
 
23
- This documentation is intended to be used by dd-trace-rb developers. Please see the `docs/` folder for user-level
24
- documentation.
24
+ **This documentation is intended to be used by dd-trace-rb developers. Please see the `docs/` folder for user-level
25
+ documentation.**
25
26
 
26
27
  ## Must not block or break users that cannot use it
27
28
 
@@ -118,3 +119,38 @@ Note that `pthread_getcpuclockid()` is not available on macOS (nor, obviously, o
118
119
  is currently Linux-specific. Thus, in the <clock_id_from_pthread.c> file we implement the feature for supported Ruby
119
120
  setups but if something is missing we instead compile in <clock_id_noop.c> that includes a no-op implementation of the
120
121
  feature.
122
+
123
+ ## Fork-safety
124
+
125
+ It's common for Ruby applications to create child processes via the use of `fork`. For instance, this strategy is used
126
+ by the puma webserver and the resque job processing tool.
127
+
128
+ Thus, the profiler needs to be designed to take this into account. I'll call out two important parts of this design:
129
+
130
+ 1. Automatically propagate profiler to child processes. To make onboarding easier, we monkey patch the Ruby `fork` APIs
131
+ so that the profiler is automatically restarted in child processes. This way, the user only needs to start profiling at
132
+ the beginning of their application, and automatically forks are profiled as well.
133
+
134
+ 2. The profiler must ensure correctness and stability even if the application forks. There must be no impact on the
135
+ application or incorrect data generated.
136
+
137
+ ### Fork-safety for libdatadog
138
+
139
+ Since libdatadog is built in native code (Rust), special care needs to be take to consider how we're using it and how
140
+ it can be affected by the use of `fork`.
141
+
142
+ * Profile-related APIs: `Profile_new` and `Profile_add` and `Profile_free` are only called with the Ruby Global VM Lock
143
+ being held. Thus, if Ruby APIs are being used for fork, this prevents any concurrency between profile mutation and
144
+ forking, because if we’re holding the lock, then no other thread can call into the fork APIs.
145
+ (Calling libc `fork()` directly from a native extension is possible but would break the VM as well, since it does need
146
+ to do some of its own work when forking happens, so we’ll ignore that one)
147
+
148
+ * Exporter-related APIs: Explicitly to make sure we had no issues with forking, we create a new `CancellationToken_new`
149
+ and `ProfileExporterV3_new` for every report. We do release the Global VM Lock during exporting, so it's possible for
150
+ forking and exporting to be concurrent.
151
+
152
+ Both the CancellationToken and ProfileExporter are only referenced on the stack of the thread doing the exporting, so
153
+ they will not be reused in the child process after the fork. In the worst case, if a report is concurrent with a fork,
154
+ then it's possible a small amount of memory will not be cleaned up in the child process.
155
+
156
+ Because there is no leftover undefined state, we guarantee correctness for the exporter APIs.
@@ -20,5 +20,6 @@ void self_test_clock_id(void);
20
20
  // TODO: Remove this after the OldStack profiler gets removed
21
21
  VALUE clock_id_for(VALUE self, VALUE thread);
22
22
 
23
+ // Safety: This function is assumed never to raise exceptions by callers
23
24
  thread_cpu_time_id thread_cpu_time_id_for(VALUE thread);
24
25
  thread_cpu_time thread_cpu_time_for(thread_cpu_time_id time_id);
@@ -43,6 +43,7 @@ VALUE clock_id_for(DDTRACE_UNUSED VALUE _self, VALUE thread) {
43
43
  }
44
44
  }
45
45
 
46
+ // Safety: This function is assumed never to raise exceptions by callers
46
47
  thread_cpu_time_id thread_cpu_time_id_for(VALUE thread) {
47
48
  rb_nativethread_id_t thread_id = pthread_id_for(thread);
48
49
  clockid_t clock_id;