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
FunctionThatMightFail(size_t ix)19 int FunctionThatMightFail(size_t ix) {
20 return (int) ix+1;
21 }
22
23 enum ErrorCode {
24 PASS,
25 FAIL,
26 RETAKE_PREVIOUS_GRADE,
27 GOTO_JAIL_DO_NOT_PASS_GO,
28 };
29
SomeFunction(size_t ix)30 enum ErrorCode SomeFunction(size_t ix) {
31 switch (ix & 0x3) {
32 case 0:
33 return PASS;
34 case 1:
35 return FAIL;
36 }
37 return RETAKE_PREVIOUS_GRADE;
38 }
39
fake_write(size_t ix)40 ssize_t fake_write(size_t ix) {
41 return (ssize_t) ix;
42 }
43
fake_fstat(size_t ix)44 int fake_fstat(size_t ix) {
45 return (int) ix;
46 }
47
main(int ac,char ** av)48 int main(int ac, char **av) {
49 int opt;
50 size_t ix;
51 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 NaClLogModuleInit();
60
61 while (-1 != (opt = getopt(ac, av, "l:v"))) {
62 switch (opt) {
63 case 'v':
64 NaClLogIncrVerbosity();
65 break;
66 case 'l':
67 limit = strtoul(optarg, (char **) NULL, 0);
68 break;
69 default:
70 fprintf(stderr,
71 "Usage: nacl_fi_test [-v]\n");
72 return 1;
73 }
74 }
75 NaClFaultInjectionModuleInit();
76
77 for (ix = 0; ix < limit; ++ix) {
78 printf("%d\n", NACL_FI("test", FunctionThatMightFail(ix), -1));
79 buffer = NACL_FI("alloc", malloc(ix+1), NULL);
80 if (NULL == buffer) {
81 printf("allocation for %"NACL_PRIdS" bytes failed\n", ix+1);
82 } else {
83 free(buffer);
84 buffer = NULL;
85 }
86 err = NACL_FI_VAL("ret", enum ErrorCode, SomeFunction(ix));
87 if (err != expected[ix & 0x3]) {
88 printf("Unexpected return %d, expected %d\n",
89 err, expected[ix & 0x3]);
90 }
91 if (-1 == NACL_FI_SYSCALL("fstat", fake_fstat(ix))) {
92 printf("fstat failed, errno %d\n", errno);
93 }
94 if (-1 == (write_result =
95 NACL_FI_TYPED_SYSCALL("write", ssize_t, fake_write(ix)))) {
96 printf("write failed, errno %d\n", errno);
97 } else if (write_result != (ssize_t) ix) {
98 printf("unexpected write count %"NACL_PRIdS", expected %"NACL_PRIuS"\n",
99 write_result, ix);
100 }
101 }
102 return 0;
103 }
104