pf2 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -2
  3. data/Cargo.lock +650 -0
  4. data/Cargo.toml +3 -0
  5. data/README.md +110 -13
  6. data/Rakefile +8 -0
  7. data/crates/backtrace-sys2/.gitignore +1 -0
  8. data/crates/backtrace-sys2/Cargo.toml +9 -0
  9. data/crates/backtrace-sys2/build.rs +48 -0
  10. data/crates/backtrace-sys2/src/lib.rs +5 -0
  11. data/crates/backtrace-sys2/src/libbacktrace/.gitignore +15 -0
  12. data/crates/backtrace-sys2/src/libbacktrace/Isaac.Newton-Opticks.txt +9286 -0
  13. data/crates/backtrace-sys2/src/libbacktrace/LICENSE +29 -0
  14. data/crates/backtrace-sys2/src/libbacktrace/Makefile.am +623 -0
  15. data/crates/backtrace-sys2/src/libbacktrace/Makefile.in +2666 -0
  16. data/crates/backtrace-sys2/src/libbacktrace/README.md +36 -0
  17. data/crates/backtrace-sys2/src/libbacktrace/aclocal.m4 +864 -0
  18. data/crates/backtrace-sys2/src/libbacktrace/alloc.c +167 -0
  19. data/crates/backtrace-sys2/src/libbacktrace/allocfail.c +136 -0
  20. data/crates/backtrace-sys2/src/libbacktrace/allocfail.sh +104 -0
  21. data/crates/backtrace-sys2/src/libbacktrace/atomic.c +113 -0
  22. data/crates/backtrace-sys2/src/libbacktrace/backtrace-supported.h.in +66 -0
  23. data/crates/backtrace-sys2/src/libbacktrace/backtrace.c +129 -0
  24. data/crates/backtrace-sys2/src/libbacktrace/backtrace.h +189 -0
  25. data/crates/backtrace-sys2/src/libbacktrace/btest.c +501 -0
  26. data/crates/backtrace-sys2/src/libbacktrace/compile +348 -0
  27. data/crates/backtrace-sys2/src/libbacktrace/config/enable.m4 +38 -0
  28. data/crates/backtrace-sys2/src/libbacktrace/config/lead-dot.m4 +31 -0
  29. data/crates/backtrace-sys2/src/libbacktrace/config/libtool.m4 +7436 -0
  30. data/crates/backtrace-sys2/src/libbacktrace/config/ltoptions.m4 +369 -0
  31. data/crates/backtrace-sys2/src/libbacktrace/config/ltsugar.m4 +123 -0
  32. data/crates/backtrace-sys2/src/libbacktrace/config/ltversion.m4 +23 -0
  33. data/crates/backtrace-sys2/src/libbacktrace/config/lt~obsolete.m4 +98 -0
  34. data/crates/backtrace-sys2/src/libbacktrace/config/multi.m4 +68 -0
  35. data/crates/backtrace-sys2/src/libbacktrace/config/override.m4 +117 -0
  36. data/crates/backtrace-sys2/src/libbacktrace/config/unwind_ipinfo.m4 +37 -0
  37. data/crates/backtrace-sys2/src/libbacktrace/config/warnings.m4 +227 -0
  38. data/crates/backtrace-sys2/src/libbacktrace/config.guess +1700 -0
  39. data/crates/backtrace-sys2/src/libbacktrace/config.h.in +182 -0
  40. data/crates/backtrace-sys2/src/libbacktrace/config.sub +1885 -0
  41. data/crates/backtrace-sys2/src/libbacktrace/configure +15740 -0
  42. data/crates/backtrace-sys2/src/libbacktrace/configure.ac +613 -0
  43. data/crates/backtrace-sys2/src/libbacktrace/dwarf.c +4402 -0
  44. data/crates/backtrace-sys2/src/libbacktrace/edtest.c +120 -0
  45. data/crates/backtrace-sys2/src/libbacktrace/edtest2.c +43 -0
  46. data/crates/backtrace-sys2/src/libbacktrace/elf.c +7443 -0
  47. data/crates/backtrace-sys2/src/libbacktrace/fileline.c +407 -0
  48. data/crates/backtrace-sys2/src/libbacktrace/filenames.h +52 -0
  49. data/crates/backtrace-sys2/src/libbacktrace/filetype.awk +13 -0
  50. data/crates/backtrace-sys2/src/libbacktrace/install-debuginfo-for-buildid.sh.in +65 -0
  51. data/crates/backtrace-sys2/src/libbacktrace/install-sh +501 -0
  52. data/crates/backtrace-sys2/src/libbacktrace/instrumented_alloc.c +114 -0
  53. data/crates/backtrace-sys2/src/libbacktrace/internal.h +389 -0
  54. data/crates/backtrace-sys2/src/libbacktrace/libtool.m4 +7436 -0
  55. data/crates/backtrace-sys2/src/libbacktrace/ltmain.sh +8636 -0
  56. data/crates/backtrace-sys2/src/libbacktrace/ltoptions.m4 +369 -0
  57. data/crates/backtrace-sys2/src/libbacktrace/ltsugar.m4 +123 -0
  58. data/crates/backtrace-sys2/src/libbacktrace/ltversion.m4 +23 -0
  59. data/crates/backtrace-sys2/src/libbacktrace/lt~obsolete.m4 +98 -0
  60. data/crates/backtrace-sys2/src/libbacktrace/macho.c +1355 -0
  61. data/crates/backtrace-sys2/src/libbacktrace/missing +215 -0
  62. data/crates/backtrace-sys2/src/libbacktrace/mmap.c +331 -0
  63. data/crates/backtrace-sys2/src/libbacktrace/mmapio.c +110 -0
  64. data/crates/backtrace-sys2/src/libbacktrace/move-if-change +83 -0
  65. data/crates/backtrace-sys2/src/libbacktrace/mtest.c +410 -0
  66. data/crates/backtrace-sys2/src/libbacktrace/nounwind.c +66 -0
  67. data/crates/backtrace-sys2/src/libbacktrace/pecoff.c +957 -0
  68. data/crates/backtrace-sys2/src/libbacktrace/posix.c +104 -0
  69. data/crates/backtrace-sys2/src/libbacktrace/print.c +92 -0
  70. data/crates/backtrace-sys2/src/libbacktrace/read.c +110 -0
  71. data/crates/backtrace-sys2/src/libbacktrace/simple.c +108 -0
  72. data/crates/backtrace-sys2/src/libbacktrace/sort.c +108 -0
  73. data/crates/backtrace-sys2/src/libbacktrace/state.c +72 -0
  74. data/crates/backtrace-sys2/src/libbacktrace/stest.c +137 -0
  75. data/crates/backtrace-sys2/src/libbacktrace/test-driver +148 -0
  76. data/crates/backtrace-sys2/src/libbacktrace/test_format.c +55 -0
  77. data/crates/backtrace-sys2/src/libbacktrace/testlib.c +234 -0
  78. data/crates/backtrace-sys2/src/libbacktrace/testlib.h +110 -0
  79. data/crates/backtrace-sys2/src/libbacktrace/ttest.c +161 -0
  80. data/crates/backtrace-sys2/src/libbacktrace/unittest.c +92 -0
  81. data/crates/backtrace-sys2/src/libbacktrace/unknown.c +65 -0
  82. data/crates/backtrace-sys2/src/libbacktrace/xcoff.c +1606 -0
  83. data/crates/backtrace-sys2/src/libbacktrace/xztest.c +508 -0
  84. data/crates/backtrace-sys2/src/libbacktrace/zstdtest.c +523 -0
  85. data/crates/backtrace-sys2/src/libbacktrace/ztest.c +541 -0
  86. data/ext/pf2/Cargo.toml +25 -0
  87. data/ext/pf2/build.rs +3 -0
  88. data/ext/pf2/extconf.rb +6 -1
  89. data/ext/pf2/src/backtrace.rs +126 -0
  90. data/ext/pf2/src/lib.rs +15 -0
  91. data/ext/pf2/src/profile.rs +65 -0
  92. data/ext/pf2/src/profile_serializer.rs +204 -0
  93. data/ext/pf2/src/ringbuffer.rs +152 -0
  94. data/ext/pf2/src/ruby_init.rs +74 -0
  95. data/ext/pf2/src/sample.rs +66 -0
  96. data/ext/pf2/src/siginfo_t.c +5 -0
  97. data/ext/pf2/src/signal_scheduler/configuration.rs +31 -0
  98. data/ext/pf2/src/signal_scheduler/timer_installer.rs +199 -0
  99. data/ext/pf2/src/signal_scheduler.rs +311 -0
  100. data/ext/pf2/src/timer_thread_scheduler.rs +319 -0
  101. data/ext/pf2/src/util.rs +30 -0
  102. data/lib/pf2/cli.rb +1 -1
  103. data/lib/pf2/reporter.rb +48 -16
  104. data/lib/pf2/version.rb +1 -1
  105. data/lib/pf2.rb +20 -5
  106. metadata +128 -5
  107. data/ext/pf2/pf2.c +0 -246
@@ -0,0 +1,541 @@
1
+ /* ztest.c -- Test for libbacktrace inflate code.
2
+ Copyright (C) 2017-2021 Free Software Foundation, Inc.
3
+ Written by Ian Lance Taylor, Google.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are
7
+ met:
8
+
9
+ (1) Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions and the following disclaimer.
11
+
12
+ (2) Redistributions in binary form must reproduce the above copyright
13
+ notice, this list of conditions and the following disclaimer in
14
+ the documentation and/or other materials provided with the
15
+ distribution.
16
+
17
+ (3) The name of the author may not be used to
18
+ endorse or promote products derived from this software without
19
+ specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
+ POSSIBILITY OF SUCH DAMAGE. */
32
+
33
+ #include "config.h"
34
+
35
+ #include <errno.h>
36
+ #include <stdio.h>
37
+ #include <stdlib.h>
38
+ #include <string.h>
39
+ #include <time.h>
40
+ #include <sys/types.h>
41
+ #include <sys/stat.h>
42
+
43
+ #ifdef HAVE_ZLIB
44
+ #include <zlib.h>
45
+ #endif
46
+
47
+ #include "backtrace.h"
48
+ #include "backtrace-supported.h"
49
+
50
+ #include "internal.h"
51
+ #include "testlib.h"
52
+
53
+ #ifndef HAVE_CLOCK_GETTIME
54
+
55
+ typedef int xclockid_t;
56
+
57
+ static int
58
+ xclock_gettime (xclockid_t id ATTRIBUTE_UNUSED,
59
+ struct timespec *ts ATTRIBUTE_UNUSED)
60
+ {
61
+ errno = EINVAL;
62
+ return -1;
63
+ }
64
+
65
+ #define clockid_t xclockid_t
66
+ #define clock_gettime xclock_gettime
67
+ #undef CLOCK_REALTIME
68
+ #define CLOCK_REALTIME 0
69
+
70
+ #endif /* !defined(HAVE_CLOCK_GETTIME) */
71
+
72
+ #ifdef CLOCK_PROCESS_CPUTIME_ID
73
+ #define ZLIB_CLOCK_GETTIME_ARG CLOCK_PROCESS_CPUTIME_ID
74
+ #else
75
+ #define ZLIB_CLOCK_GETTIME_ARG CLOCK_REALTIME
76
+ #endif
77
+
78
+ /* Some tests for the local zlib inflation code. */
79
+
80
+ struct zlib_test
81
+ {
82
+ const char *name;
83
+ const char *uncompressed;
84
+ size_t uncompressed_len;
85
+ const char *compressed;
86
+ size_t compressed_len;
87
+ };
88
+
89
+ /* Error callback. */
90
+
91
+ static void
92
+ error_callback_compress (void *vdata ATTRIBUTE_UNUSED, const char *msg,
93
+ int errnum)
94
+ {
95
+ fprintf (stderr, "%s", msg);
96
+ if (errnum > 0)
97
+ fprintf (stderr, ": %s", strerror (errnum));
98
+ fprintf (stderr, "\n");
99
+ exit (EXIT_FAILURE);
100
+ }
101
+
102
+ static const struct zlib_test tests[] =
103
+ {
104
+ {
105
+ "empty",
106
+ "",
107
+ 0,
108
+ "\x78\x9c\x03\x00\x00\x00\x00\x01",
109
+ 8,
110
+ },
111
+ {
112
+ "hello",
113
+ "hello, world\n",
114
+ 0,
115
+ ("\x78\x9c\xca\x48\xcd\xc9\xc9\xd7\x51\x28\xcf"
116
+ "\x2f\xca\x49\xe1\x02\x04\x00\x00\xff\xff\x21\xe7\x04\x93"),
117
+ 25,
118
+ },
119
+ {
120
+ "goodbye",
121
+ "goodbye, world",
122
+ 0,
123
+ ("\x78\x9c\x4b\xcf\xcf\x4f\x49\xaa"
124
+ "\x4c\xd5\x51\x28\xcf\x2f\xca\x49"
125
+ "\x01\x00\x28\xa5\x05\x5e"),
126
+ 22,
127
+ },
128
+ {
129
+ "ranges",
130
+ ("\xcc\x11\x00\x00\x00\x00\x00\x00\xd5\x13\x00\x00\x00\x00\x00\x00"
131
+ "\x1c\x14\x00\x00\x00\x00\x00\x00\x72\x14\x00\x00\x00\x00\x00\x00"
132
+ "\x9d\x14\x00\x00\x00\x00\x00\x00\xd5\x14\x00\x00\x00\x00\x00\x00"
133
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
134
+ "\xfb\x12\x00\x00\x00\x00\x00\x00\x09\x13\x00\x00\x00\x00\x00\x00"
135
+ "\x0c\x13\x00\x00\x00\x00\x00\x00\xcb\x13\x00\x00\x00\x00\x00\x00"
136
+ "\x29\x14\x00\x00\x00\x00\x00\x00\x4e\x14\x00\x00\x00\x00\x00\x00"
137
+ "\x9d\x14\x00\x00\x00\x00\x00\x00\xd5\x14\x00\x00\x00\x00\x00\x00"
138
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
139
+ "\xfb\x12\x00\x00\x00\x00\x00\x00\x09\x13\x00\x00\x00\x00\x00\x00"
140
+ "\x67\x13\x00\x00\x00\x00\x00\x00\xcb\x13\x00\x00\x00\x00\x00\x00"
141
+ "\x9d\x14\x00\x00\x00\x00\x00\x00\xd5\x14\x00\x00\x00\x00\x00\x00"
142
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
143
+ "\x5f\x0b\x00\x00\x00\x00\x00\x00\x6c\x0b\x00\x00\x00\x00\x00\x00"
144
+ "\x7d\x0b\x00\x00\x00\x00\x00\x00\x7e\x0c\x00\x00\x00\x00\x00\x00"
145
+ "\x38\x0f\x00\x00\x00\x00\x00\x00\x5c\x0f\x00\x00\x00\x00\x00\x00"
146
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
147
+ "\x83\x0c\x00\x00\x00\x00\x00\x00\xfa\x0c\x00\x00\x00\x00\x00\x00"
148
+ "\xfd\x0d\x00\x00\x00\x00\x00\x00\xef\x0e\x00\x00\x00\x00\x00\x00"
149
+ "\x14\x0f\x00\x00\x00\x00\x00\x00\x38\x0f\x00\x00\x00\x00\x00\x00"
150
+ "\x9f\x0f\x00\x00\x00\x00\x00\x00\xac\x0f\x00\x00\x00\x00\x00\x00"
151
+ "\xdb\x0f\x00\x00\x00\x00\x00\x00\xff\x0f\x00\x00\x00\x00\x00\x00"
152
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
153
+ "\xfd\x0d\x00\x00\x00\x00\x00\x00\xd8\x0e\x00\x00\x00\x00\x00\x00"
154
+ "\x9f\x0f\x00\x00\x00\x00\x00\x00\xac\x0f\x00\x00\x00\x00\x00\x00"
155
+ "\xdb\x0f\x00\x00\x00\x00\x00\x00\xff\x0f\x00\x00\x00\x00\x00\x00"
156
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
157
+ "\xfa\x0c\x00\x00\x00\x00\x00\x00\xea\x0d\x00\x00\x00\x00\x00\x00"
158
+ "\xef\x0e\x00\x00\x00\x00\x00\x00\x14\x0f\x00\x00\x00\x00\x00\x00"
159
+ "\x5c\x0f\x00\x00\x00\x00\x00\x00\x9f\x0f\x00\x00\x00\x00\x00\x00"
160
+ "\xac\x0f\x00\x00\x00\x00\x00\x00\xdb\x0f\x00\x00\x00\x00\x00\x00"
161
+ "\xff\x0f\x00\x00\x00\x00\x00\x00\x2c\x10\x00\x00\x00\x00\x00\x00"
162
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
163
+ "\x60\x11\x00\x00\x00\x00\x00\x00\xd1\x16\x00\x00\x00\x00\x00\x00"
164
+ "\x40\x0b\x00\x00\x00\x00\x00\x00\x2c\x10\x00\x00\x00\x00\x00\x00"
165
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
166
+ "\x7a\x00\x00\x00\x00\x00\x00\x00\xb6\x00\x00\x00\x00\x00\x00\x00"
167
+ "\x9f\x01\x00\x00\x00\x00\x00\x00\xa7\x01\x00\x00\x00\x00\x00\x00"
168
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
169
+ "\x7a\x00\x00\x00\x00\x00\x00\x00\xa9\x00\x00\x00\x00\x00\x00\x00"
170
+ "\x9f\x01\x00\x00\x00\x00\x00\x00\xa7\x01\x00\x00\x00\x00\x00\x00"
171
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
172
+ 672,
173
+ ("\x78\x9c\x3b\x23\xc8\x00\x06\x57\x85\x21\xb4\x8c\x08\x84\x2e\x82"
174
+ "\xd2\x73\xa1\xf4\x55\x28\x8d\x0e\x7e\x0b\x41\x68\x4e\xa8\x7e\x1e"
175
+ "\x28\x7d\x1a\x4a\x6b\x42\xf5\xf9\x91\x69\x5e\x3a\x9a\x79\x84\xf4"
176
+ "\xc7\x73\x43\xe8\x1c\x28\x5d\x0b\xa5\xeb\x78\x20\xb4\x05\x3f\x84"
177
+ "\x8e\xe1\xc7\xae\xbf\x19\xaa\xee\x17\x94\xfe\xcb\x0b\xa1\xdf\xf3"
178
+ "\x41\x68\x11\x7e\x54\x73\xe6\x43\xe9\x35\x50\xfa\x36\x94\xfe\x8f"
179
+ "\xc3\x7c\x98\x79\x37\xf8\xc8\xd3\x0f\x73\xd7\x2b\x1c\xee\x8a\x21"
180
+ "\xd2\x5d\x3a\x02\xd8\xcd\x4f\x80\xa6\x87\x8b\x62\x10\xda\x81\x1b"
181
+ "\xbf\xfa\x2a\x28\xbd\x0d\x4a\xcf\x67\x84\xd0\xcb\x19\xf1\xab\x5f"
182
+ "\x49\xa4\x7a\x00\x48\x97\x29\xd4"),
183
+ 152,
184
+ }
185
+ };
186
+
187
+ /* Test the hand coded samples. */
188
+
189
+ static void
190
+ test_samples (struct backtrace_state *state)
191
+ {
192
+ size_t i;
193
+
194
+ for (i = 0; i < sizeof tests / sizeof tests[0]; ++i)
195
+ {
196
+ char *p;
197
+ size_t v;
198
+ size_t j;
199
+ unsigned char *uncompressed;
200
+ size_t uncompressed_len;
201
+
202
+ p = malloc (12 + tests[i].compressed_len);
203
+ memcpy (p, "ZLIB", 4);
204
+ v = tests[i].uncompressed_len;
205
+ if (v == 0)
206
+ v = strlen (tests[i].uncompressed);
207
+ for (j = 0; j < 8; ++j)
208
+ p[j + 4] = (v >> ((7 - j) * 8)) & 0xff;
209
+ memcpy (p + 12, tests[i].compressed, tests[i].compressed_len);
210
+ uncompressed = NULL;
211
+ uncompressed_len = 0;
212
+ if (!backtrace_uncompress_zdebug (state, (unsigned char *) p,
213
+ tests[i].compressed_len + 12,
214
+ error_callback_compress, NULL,
215
+ &uncompressed, &uncompressed_len))
216
+ {
217
+ fprintf (stderr, "test %s: uncompress failed\n", tests[i].name);
218
+ ++failures;
219
+ }
220
+ else
221
+ {
222
+ if (uncompressed_len != v)
223
+ {
224
+ fprintf (stderr,
225
+ "test %s: got uncompressed length %zu, want %zu\n",
226
+ tests[i].name, uncompressed_len, v);
227
+ ++failures;
228
+ }
229
+ else if (memcmp (tests[i].uncompressed, uncompressed, v) != 0)
230
+ {
231
+ size_t j;
232
+
233
+ fprintf (stderr, "test %s: uncompressed data mismatch\n",
234
+ tests[i].name);
235
+ for (j = 0; j < v; ++j)
236
+ if (tests[i].uncompressed[j] != uncompressed[j])
237
+ fprintf (stderr, " %zu: got %#x want %#x\n", j,
238
+ uncompressed[j], tests[i].uncompressed[j]);
239
+ ++failures;
240
+ }
241
+ else
242
+ printf ("PASS: inflate %s\n", tests[i].name);
243
+
244
+ backtrace_free (state, uncompressed, uncompressed_len,
245
+ error_callback_compress, NULL);
246
+ }
247
+ }
248
+ }
249
+
250
+ #ifdef HAVE_ZLIB
251
+
252
+ /* Given a set of TRIALS timings, discard the lowest and highest
253
+ values and return the mean average of the rest. */
254
+
255
+ static size_t
256
+ average_time (const size_t *times, size_t trials)
257
+ {
258
+ size_t imax;
259
+ size_t max;
260
+ size_t imin;
261
+ size_t min;
262
+ size_t i;
263
+ size_t sum;
264
+
265
+ imin = 0;
266
+ imax = 0;
267
+ min = times[0];
268
+ max = times[0];
269
+ for (i = 1; i < trials; ++i)
270
+ {
271
+ if (times[i] < min)
272
+ {
273
+ imin = i;
274
+ min = times[i];
275
+ }
276
+ if (times[i] > max)
277
+ {
278
+ imax = i;
279
+ max = times[i];
280
+ }
281
+ }
282
+
283
+ sum = 0;
284
+ for (i = 0; i < trials; ++i)
285
+ {
286
+ if (i != imax && i != imin)
287
+ sum += times[i];
288
+ }
289
+ return sum / (trials - 2);
290
+ }
291
+
292
+ #endif
293
+
294
+ /* Test a larger text, if available. */
295
+
296
+ static void
297
+ test_large (struct backtrace_state *state ATTRIBUTE_UNUSED)
298
+ {
299
+ #ifdef HAVE_ZLIB
300
+ unsigned char *orig_buf;
301
+ size_t orig_bufsize;
302
+ size_t i;
303
+ char *compressed_buf;
304
+ size_t compressed_bufsize;
305
+ unsigned long compress_sizearg;
306
+ unsigned char *uncompressed_buf;
307
+ size_t uncompressed_bufsize;
308
+ int r;
309
+ clockid_t cid;
310
+ struct timespec ts1;
311
+ struct timespec ts2;
312
+ size_t ctime;
313
+ size_t ztime;
314
+ const size_t trials = 16;
315
+ size_t ctimes[16];
316
+ size_t ztimes[16];
317
+ static const char * const names[] = {
318
+ "Isaac.Newton-Opticks.txt",
319
+ "../libgo/go/testdata/Isaac.Newton-Opticks.txt",
320
+ };
321
+
322
+ orig_buf = NULL;
323
+ orig_bufsize = 0;
324
+ uncompressed_buf = NULL;
325
+ compressed_buf = NULL;
326
+
327
+ for (i = 0; i < sizeof names / sizeof names[0]; ++i)
328
+ {
329
+ size_t len;
330
+ char *namebuf;
331
+ FILE *e;
332
+ struct stat st;
333
+ char *rbuf;
334
+ size_t got;
335
+
336
+ len = strlen (SRCDIR) + strlen (names[i]) + 2;
337
+ namebuf = malloc (len);
338
+ if (namebuf == NULL)
339
+ {
340
+ perror ("malloc");
341
+ goto fail;
342
+ }
343
+ snprintf (namebuf, len, "%s/%s", SRCDIR, names[i]);
344
+ e = fopen (namebuf, "r");
345
+ free (namebuf);
346
+ if (e == NULL)
347
+ continue;
348
+ if (fstat (fileno (e), &st) < 0)
349
+ {
350
+ perror ("fstat");
351
+ fclose (e);
352
+ continue;
353
+ }
354
+ rbuf = malloc (st.st_size);
355
+ if (rbuf == NULL)
356
+ {
357
+ perror ("malloc");
358
+ goto fail;
359
+ }
360
+ got = fread (rbuf, 1, st.st_size, e);
361
+ fclose (e);
362
+ if (got > 0)
363
+ {
364
+ orig_buf = (unsigned char *) rbuf;
365
+ orig_bufsize = got;
366
+ break;
367
+ }
368
+ free (rbuf);
369
+ }
370
+
371
+ if (orig_buf == NULL)
372
+ {
373
+ /* We couldn't find an input file. */
374
+ printf ("UNSUPPORTED: inflate large\n");
375
+ return;
376
+ }
377
+
378
+ compressed_bufsize = compressBound (orig_bufsize) + 12;
379
+ compressed_buf = malloc (compressed_bufsize);
380
+ if (compressed_buf == NULL)
381
+ {
382
+ perror ("malloc");
383
+ goto fail;
384
+ }
385
+
386
+ compress_sizearg = compressed_bufsize - 12;
387
+ r = compress ((unsigned char *) compressed_buf + 12, &compress_sizearg,
388
+ orig_buf, orig_bufsize);
389
+ if (r != Z_OK)
390
+ {
391
+ fprintf (stderr, "zlib compress failed: %d\n", r);
392
+ goto fail;
393
+ }
394
+
395
+ compressed_bufsize = compress_sizearg + 12;
396
+
397
+ /* Prepare the header that our library expects. */
398
+ memcpy (compressed_buf, "ZLIB", 4);
399
+ for (i = 0; i < 8; ++i)
400
+ compressed_buf[i + 4] = (orig_bufsize >> ((7 - i) * 8)) & 0xff;
401
+
402
+ uncompressed_buf = malloc (orig_bufsize);
403
+ if (uncompressed_buf == NULL)
404
+ {
405
+ perror ("malloc");
406
+ goto fail;
407
+ }
408
+ uncompressed_bufsize = orig_bufsize;
409
+
410
+ if (!backtrace_uncompress_zdebug (state, (unsigned char *) compressed_buf,
411
+ compressed_bufsize,
412
+ error_callback_compress, NULL,
413
+ &uncompressed_buf, &uncompressed_bufsize))
414
+ {
415
+ fprintf (stderr, "inflate large: backtrace_uncompress_zdebug failed\n");
416
+ goto fail;
417
+ }
418
+
419
+ if (uncompressed_bufsize != orig_bufsize)
420
+ {
421
+ fprintf (stderr,
422
+ "inflate large: got uncompressed length %zu, want %zu\n",
423
+ uncompressed_bufsize, orig_bufsize);
424
+ goto fail;
425
+ }
426
+
427
+ if (memcmp (uncompressed_buf, orig_buf, uncompressed_bufsize) != 0)
428
+ {
429
+ fprintf (stderr, "inflate large: uncompressed data mismatch\n");
430
+ goto fail;
431
+ }
432
+
433
+ printf ("PASS: inflate large\n");
434
+
435
+ for (i = 0; i < trials; ++i)
436
+ {
437
+ unsigned long uncompress_sizearg;
438
+
439
+ cid = ZLIB_CLOCK_GETTIME_ARG;
440
+ if (clock_gettime (cid, &ts1) < 0)
441
+ {
442
+ if (errno == EINVAL)
443
+ return;
444
+ perror ("clock_gettime");
445
+ return;
446
+ }
447
+
448
+ if (!backtrace_uncompress_zdebug (state,
449
+ (unsigned char *) compressed_buf,
450
+ compressed_bufsize,
451
+ error_callback_compress, NULL,
452
+ &uncompressed_buf,
453
+ &uncompressed_bufsize))
454
+ {
455
+ fprintf (stderr,
456
+ ("inflate large: "
457
+ "benchmark backtrace_uncompress_zdebug failed\n"));
458
+ return;
459
+ }
460
+
461
+ if (clock_gettime (cid, &ts2) < 0)
462
+ {
463
+ perror ("clock_gettime");
464
+ return;
465
+ }
466
+
467
+ ctime = (ts2.tv_sec - ts1.tv_sec) * 1000000000;
468
+ ctime += ts2.tv_nsec - ts1.tv_nsec;
469
+ ctimes[i] = ctime;
470
+
471
+ if (clock_gettime (cid, &ts1) < 0)
472
+ {
473
+ perror("clock_gettime");
474
+ return;
475
+ }
476
+
477
+ uncompress_sizearg = uncompressed_bufsize;
478
+ r = uncompress ((unsigned char *) uncompressed_buf, &uncompress_sizearg,
479
+ (unsigned char *) compressed_buf + 12,
480
+ compressed_bufsize - 12);
481
+
482
+ if (clock_gettime (cid, &ts2) < 0)
483
+ {
484
+ perror ("clock_gettime");
485
+ return;
486
+ }
487
+
488
+ if (r != Z_OK)
489
+ {
490
+ fprintf (stderr,
491
+ "inflate large: benchmark zlib uncompress failed: %d\n",
492
+ r);
493
+ return;
494
+ }
495
+
496
+ ztime = (ts2.tv_sec - ts1.tv_sec) * 1000000000;
497
+ ztime += ts2.tv_nsec - ts1.tv_nsec;
498
+ ztimes[i] = ztime;
499
+ }
500
+
501
+ /* Toss the highest and lowest times and average the rest. */
502
+ ctime = average_time (ctimes, trials);
503
+ ztime = average_time (ztimes, trials);
504
+
505
+ printf ("backtrace: %zu ns\n", ctime);
506
+ printf ("zlib : %zu ns\n", ztime);
507
+ printf ("ratio : %g\n", (double) ztime / (double) ctime);
508
+
509
+ return;
510
+
511
+ fail:
512
+ printf ("FAIL: inflate large\n");
513
+ ++failures;
514
+
515
+ if (orig_buf != NULL)
516
+ free (orig_buf);
517
+ if (compressed_buf != NULL)
518
+ free (compressed_buf);
519
+ if (uncompressed_buf != NULL)
520
+ free (uncompressed_buf);
521
+
522
+ #else /* !HAVE_ZLIB */
523
+
524
+ printf ("UNSUPPORTED: inflate large\n");
525
+
526
+ #endif /* !HAVE_ZLIB */
527
+ }
528
+
529
+ int
530
+ main (int argc ATTRIBUTE_UNUSED, char **argv)
531
+ {
532
+ struct backtrace_state *state;
533
+
534
+ state = backtrace_create_state (argv[0], BACKTRACE_SUPPORTS_THREADS,
535
+ error_callback_create, NULL);
536
+
537
+ test_samples (state);
538
+ test_large (state);
539
+
540
+ exit (failures != 0 ? EXIT_FAILURE : EXIT_SUCCESS);
541
+ }
@@ -0,0 +1,25 @@
1
+ [package]
2
+ name = "pf2"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+ authors = ["Daisuke Aritomo <osyoyu@osyoyu.com>"]
6
+ publish = false
7
+
8
+ [lib]
9
+ crate-type = ["cdylib"]
10
+
11
+ [dependencies]
12
+ backtrace-sys2 = { path = "../../crates/backtrace-sys2" }
13
+ env_logger = { version = "0.11.0", optional = true }
14
+ libc = "0.2.149"
15
+ log = "0.4.20"
16
+ rb-sys = { version = "0.9.82", features = ["stable-api", "stable-api-compiled-testing"] } # using stable-api-compiled-testing for generating bindings from Ruby source
17
+ serde = "1.0.189"
18
+ serde_derive = "1.0.189"
19
+ serde_json = "1.0.107"
20
+
21
+ [build-dependencies]
22
+ cc = "1.0.83"
23
+
24
+ [features]
25
+ debug = ["env_logger"]
data/ext/pf2/build.rs ADDED
@@ -0,0 +1,3 @@
1
+ fn main() {
2
+ cc::Build::new().file("src/siginfo_t.c").compile("ccode");
3
+ }
data/ext/pf2/extconf.rb CHANGED
@@ -1,5 +1,10 @@
1
1
  require 'mkmf'
2
+ require 'rb_sys/mkmf'
2
3
 
3
4
  abort 'missing rb_profile_thread_frames()' unless have_func 'rb_profile_thread_frames'
4
5
 
5
- create_makefile 'pf2/pf2'
6
+ create_rust_makefile 'pf2/pf2' do |r|
7
+ if ENV['PF2_FEATURES']
8
+ r.features = ENV['PF2_FEATURES'].split(",")
9
+ end
10
+ end
@@ -0,0 +1,126 @@
1
+ use std::ffi::{c_char, c_int, CStr};
2
+
3
+ use libc::c_void;
4
+
5
+ #[derive(Debug)]
6
+ pub struct BacktraceState {
7
+ ptr: *mut backtrace_sys2::backtrace_state,
8
+ }
9
+
10
+ unsafe impl Send for BacktraceState {}
11
+ unsafe impl Sync for BacktraceState {}
12
+
13
+ impl BacktraceState {
14
+ pub unsafe fn new(ptr: *mut backtrace_sys2::backtrace_state) -> Self {
15
+ Self { ptr }
16
+ }
17
+
18
+ pub fn as_mut_ptr(&self) -> *mut backtrace_sys2::backtrace_state {
19
+ self.ptr
20
+ }
21
+ }
22
+
23
+ pub struct Backtrace {}
24
+
25
+ impl Backtrace {
26
+ pub fn backtrace_simple<F>(
27
+ state: &BacktraceState,
28
+ skip: i32,
29
+ mut on_ok: F,
30
+ on_error: backtrace_sys2::backtrace_error_callback,
31
+ ) where
32
+ F: FnMut(usize) -> c_int,
33
+ {
34
+ unsafe {
35
+ backtrace_sys2::backtrace_simple(
36
+ state.as_mut_ptr(),
37
+ skip,
38
+ Some(Self::backtrace_simple_trampoline::<F>),
39
+ on_error,
40
+ &mut on_ok as *mut _ as *mut c_void,
41
+ );
42
+ }
43
+ }
44
+
45
+ pub fn backtrace_pcinfo<F>(
46
+ state: &BacktraceState,
47
+ pc: usize,
48
+ mut on_ok: F,
49
+ on_error: backtrace_sys2::backtrace_error_callback,
50
+ ) where
51
+ F: FnMut(usize, *const c_char, c_int, *const c_char) -> c_int,
52
+ {
53
+ unsafe {
54
+ backtrace_sys2::backtrace_pcinfo(
55
+ state.as_mut_ptr(),
56
+ pc,
57
+ Some(Self::backtrace_full_trampoline::<F>),
58
+ on_error,
59
+ &mut on_ok as *mut _ as *mut c_void,
60
+ );
61
+ }
62
+ }
63
+
64
+ pub fn backtrace_syminfo<F>(
65
+ state: &BacktraceState,
66
+ pc: usize,
67
+ mut on_ok: F,
68
+ on_error: backtrace_sys2::backtrace_error_callback,
69
+ ) where
70
+ F: FnMut(usize, *const c_char, usize, usize),
71
+ {
72
+ unsafe {
73
+ backtrace_sys2::backtrace_syminfo(
74
+ state.as_mut_ptr(),
75
+ pc,
76
+ Some(Self::backtrace_syminfo_trampoline::<F>),
77
+ on_error,
78
+ &mut on_ok as *mut _ as *mut c_void,
79
+ );
80
+ }
81
+ }
82
+
83
+ unsafe extern "C" fn backtrace_full_trampoline<F>(
84
+ user_data: *mut c_void,
85
+ pc: usize,
86
+ filename: *const c_char,
87
+ lineno: c_int,
88
+ function: *const c_char,
89
+ ) -> c_int
90
+ where
91
+ F: FnMut(usize, *const c_char, c_int, *const c_char) -> c_int,
92
+ {
93
+ let user_data = &mut *(user_data as *mut F);
94
+ user_data(pc, filename, lineno, function)
95
+ }
96
+
97
+ unsafe extern "C" fn backtrace_simple_trampoline<F>(user_data: *mut c_void, pc: usize) -> c_int
98
+ where
99
+ F: FnMut(usize) -> c_int,
100
+ {
101
+ let user_data = &mut *(user_data as *mut F);
102
+ user_data(pc)
103
+ }
104
+
105
+ unsafe extern "C" fn backtrace_syminfo_trampoline<F>(
106
+ user_data: *mut c_void,
107
+ pc: usize,
108
+ symname: *const c_char,
109
+ symval: usize,
110
+ symsize: usize,
111
+ ) where
112
+ F: FnMut(usize, *const c_char, usize, usize),
113
+ {
114
+ let user_data = &mut *(user_data as *mut F);
115
+ user_data(pc, symname, symval, symsize);
116
+ }
117
+
118
+ pub unsafe extern "C" fn backtrace_error_callback(
119
+ _data: *mut c_void,
120
+ msg: *const c_char,
121
+ errnum: c_int,
122
+ ) {
123
+ let msg = unsafe { CStr::from_ptr(msg) };
124
+ log::debug!("backtrace error: {:?} ({})", msg, errnum);
125
+ }
126
+ }