File: ondemand_assert_out_of_order_values.cpp

package info (click to toggle)
simdjson 4.3.1-4
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 31,396 kB
  • sloc: cpp: 195,760; ansic: 20,954; sh: 1,126; python: 885; makefile: 47; ruby: 25; javascript: 13
file content (80 lines) | stat: -rw-r--r-- 2,121 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include "simdjson.h"


// We get spurious "maybe used uninitialized" warnings under GCC 12.
using namespace simdjson;
#if defined(__GNUC__) && !defined(__clang__)
#if __GNUC__ >= 12
SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
#endif
#endif

// This ensures the compiler can't rearrange them into the proper order (which causes it to work!)
simdjson_never_inline bool check_point(simdjson_result<ondemand::value> xval, simdjson_result<ondemand::value> yval) {
  // Verify the expected release behavior
  uint64_t x, y;
  if (!xval.get(x)) { return false; }
  if (!yval.get(y)) { return false; }
  std::cout << x << "," << y << std::endl;
  return true;
}

bool test_check_point() {
  auto json = R"(
    {
      "x": 1,
      "y": 2 3
  )"_padded;
  ondemand::parser parser;
  auto doc = parser.iterate(json);
  return check_point(doc["x"], doc["y"]);
}

// Run a test function in a fork and check whether it exited with an assert signal
template<typename F>
bool assert_test(const F& f) {
  pid_t pid = fork();
  if (pid == -1) {
    std::cerr << "fork failed" << std::endl;
    exit(1);
  }

  if (!pid) {
    //
    // This code runs in the fork (so we run the test function)
    //
    bool succeeded = f();
    exit(succeeded ? 0 : 1);
  }

  //
  // This code runs in the original executable (so we wait for the fork and check the exit code)
  //
  int exit_code = 0;
  if (waitpid(pid, &exit_code, 0) == pid_t(-1)) {
    std::cerr << "waitpid failed: " << std::string_view(strerror(errno)) << std::endl;
    exit(1);
  }

  // Test passes if the child exited with an assert signal
  return WIFSIGNALED(exit_code);
}

int main(void) {

  // To verify that the program asserts (which sends a signal), we fork a new process and use wait()
  // to check the resulting error code. If it's a signal error code, we consider the
  // test to have passed.
  // From https://stackoverflow.com/a/33694733

  bool succeeded = true;
#ifndef NDEBUG
  succeeded |= assert_test(test_check_point);
#endif
  return succeeded ? 0 : 1;
}