1 : /*
2 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * Simple fault injection test.
9 : */
10 : #include <stdio.h>
11 : #include <stdlib.h>
12 : #include <errno.h>
13 :
14 : #include "native_client/src/include/portability.h"
15 :
16 : #include "native_client/src/shared/platform/nacl_log.h"
17 : #include "native_client/src/trusted/fault_injection/fault_injection.h"
18 :
19 1 : int FunctionThatMightFail(size_t ix) {
20 1 : return (int) ix+1;
21 1 : }
22 :
23 : enum ErrorCode {
24 : PASS,
25 : FAIL,
26 : RETAKE_PREVIOUS_GRADE,
27 : GOTO_JAIL_DO_NOT_PASS_GO,
28 : };
29 :
30 1 : enum ErrorCode SomeFunction(size_t ix) {
31 1 : switch (ix & 0x3) {
32 : case 0:
33 1 : return PASS;
34 : case 1:
35 1 : return FAIL;
36 : }
37 1 : return RETAKE_PREVIOUS_GRADE;
38 1 : }
39 :
40 1 : ssize_t fake_write(size_t ix) {
41 1 : return (ssize_t) ix;
42 1 : }
43 :
44 1 : int fake_fstat(size_t ix) {
45 1 : return (int) ix;
46 1 : }
47 :
48 1 : int main(int ac, char **av) {
49 : int opt;
50 : size_t ix;
51 1 : size_t limit = 10u;
52 : char *buffer;
53 : enum ErrorCode err;
54 : static enum ErrorCode expected[4] = {
55 : PASS, FAIL, RETAKE_PREVIOUS_GRADE, RETAKE_PREVIOUS_GRADE
56 : };
57 : ssize_t write_result;
58 :
59 1 : NaClLogModuleInit();
60 :
61 1 : while (-1 != (opt = getopt(ac, av, "l:v"))) {
62 0 : switch (opt) {
63 : case 'v':
64 0 : NaClLogIncrVerbosity();
65 0 : break;
66 : case 'l':
67 0 : limit = strtoul(optarg, (char **) NULL, 0);
68 0 : break;
69 : default:
70 : fprintf(stderr,
71 0 : "Usage: nacl_fi_test [-v]\n");
72 0 : return 1;
73 : }
74 0 : }
75 1 : NaClFaultInjectionModuleInit();
76 :
77 1 : for (ix = 0; ix < limit; ++ix) {
78 1 : printf("%d\n", NACL_FI("test", FunctionThatMightFail(ix), -1));
79 1 : buffer = NACL_FI("alloc", malloc(ix+1), NULL);
80 1 : if (NULL == buffer) {
81 0 : printf("allocation for %"NACL_PRIdS" bytes failed\n", ix+1);
82 0 : } else {
83 1 : free(buffer);
84 1 : buffer = NULL;
85 : }
86 1 : err = NACL_FI_VAL("ret", enum ErrorCode, SomeFunction(ix));
87 1 : if (err != expected[ix & 0x3]) {
88 : printf("Unexpected return %d, expected %d\n",
89 0 : err, expected[ix & 0x3]);
90 : }
91 1 : if (-1 == NACL_FI_SYSCALL("fstat", fake_fstat(ix))) {
92 0 : printf("fstat failed, errno %d\n", errno);
93 : }
94 : if (-1 == (write_result =
95 1 : NACL_FI_TYPED_SYSCALL("write", ssize_t, fake_write(ix)))) {
96 0 : printf("write failed, errno %d\n", errno);
97 1 : } else if (write_result != (ssize_t) ix) {
98 : printf("unexpected write count %"NACL_PRIdS", expected %"NACL_PRIuS"\n",
99 0 : write_result, ix);
100 : }
101 1 : }
102 1 : return 0;
103 1 : }
|