- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / examples / tutorial / debugging / debugging.c
1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  */
5
6 /** @file debugging.c
7  * This example, is a modified version of hello world.  It will start a second
8  * thread and cause that thread to crash via a NULL dereference.
9  */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "ppapi/c/pp_errors.h"
15 #include "ppapi/c/pp_module.h"
16 #include "ppapi/c/pp_var.h"
17 #include "ppapi/c/ppb.h"
18 #include "ppapi/c/ppb_core.h"
19 #include "ppapi/c/ppb_instance.h"
20 #include "ppapi/c/ppb_messaging.h"
21 #include "ppapi/c/ppb_var.h"
22 #include "ppapi/c/ppp.h"
23 #include "ppapi/c/ppp_instance.h"
24 #include "ppapi/c/ppp_messaging.h"
25
26 #include <pthread.h>
27
28 #include "error_handling/error_handling.h"
29
30 PPB_Messaging* ppb_messaging_interface = NULL;
31 PPB_Var* ppb_var_interface = NULL;
32 PPB_Core* ppb_core_interface = NULL;
33
34 pthread_t g_NexeThread;
35 pthread_t g_PPAPIThread;
36 PP_Instance g_Instance;
37
38 volatile int g_CrashTime = 0;
39
40 void PostMessage(const char* str);
41
42 void layer5(int x, int y) {
43   if (g_CrashTime) {
44     *(volatile int*)x = y;
45   }
46 }
47
48 void layer4(int x) { layer5(x, 1); }
49
50 void layer3(int a, int b, int c) { layer4(a + b + c); }
51
52 void layer2(int i, int j) { layer3(i, j, 7); }
53
54 void layer1(int s, int t) {
55   int* junk = (int*)alloca(sizeof(int) * 1234);
56   junk[0] = s + 5;
57   layer2(junk[0], t + 1);
58 }
59
60 void* NexeMain(void* data) {
61   PostMessage("Running Boom thread.");
62   while (1) {
63     layer1(2, 9);
64   }
65   return NULL;
66 }
67
68 void PostMessage(const char* str) {
69   if (NULL == str)
70     return;
71   if (NULL == ppb_messaging_interface)
72     return;
73   if (0 == g_Instance)
74     return;
75
76   fprintf(stdout, "%s\n", str);
77   fflush(stdout);
78
79   if (ppb_var_interface != NULL) {
80     struct PP_Var var = ppb_var_interface->VarFromUtf8(str, strlen(str));
81     ppb_messaging_interface->PostMessage(g_Instance, var);
82     ppb_var_interface->Release(var);
83   }
84 }
85
86 void DumpJson(const char* json) {
87   const char kTrcPrefix[] = "TRC: ";
88   size_t size = sizeof(kTrcPrefix) + strlen(json) + 1;  // +1 for NULL.
89   char* out = (char*)malloc(size);
90   strcpy(out, kTrcPrefix);
91   strcat(out, json);
92
93   PostMessage(out);
94   free(out);
95 }
96
97 static PP_Bool Instance_DidCreate(PP_Instance instance,
98                                   uint32_t argc,
99                                   const char* argn[],
100                                   const char* argv[]) {
101   g_Instance = instance;
102   g_PPAPIThread = pthread_self();
103
104   PostMessage("LOG: DidCreate");
105
106   /* Request exception callbacks with JSON. */
107   EHRequestExceptionsJson(DumpJson);
108
109   /* Report back if the request was honored. */
110   if (!EHHanderInstalled()) {
111     PostMessage("LOG: Stack traces not available, so don't expect them.\n");
112   } else {
113     PostMessage("LOG: Stack traces are on.");
114   }
115   pthread_create(&g_NexeThread, NULL, NexeMain, NULL);
116   return PP_TRUE;
117 }
118
119 static void Instance_DidDestroy(PP_Instance instance) {}
120
121 static void Instance_DidChangeView(PP_Instance instance,
122                                    PP_Resource view_resource) {}
123
124 static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {}
125
126 static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance,
127                                            PP_Resource url_loader) {
128   return PP_FALSE;
129 }
130
131 /**
132  * Handles message from JavaScript.
133  *
134  * Any message from JS is a request to cause the main thread to crash.
135  */
136 static void Messaging_HandleMessage(PP_Instance instance,
137                                     struct PP_Var message) {
138   PostMessage("LOG: Got BOOM");
139   g_CrashTime = 1;
140 }
141
142 PP_EXPORT int32_t
143 PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface get_browser) {
144   ppb_messaging_interface =
145       (PPB_Messaging*)(get_browser(PPB_MESSAGING_INTERFACE));
146   ppb_var_interface = (PPB_Var*)(get_browser(PPB_VAR_INTERFACE));
147   ppb_core_interface = (PPB_Core*)(get_browser(PPB_CORE_INTERFACE));
148   return PP_OK;
149 }
150
151 PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
152   if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) {
153     static PPP_Instance instance_interface = {
154         &Instance_DidCreate,
155         &Instance_DidDestroy,
156         &Instance_DidChangeView,
157         &Instance_DidChangeFocus,
158         &Instance_HandleDocumentLoad,
159     };
160     return &instance_interface;
161   }
162   if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) {
163     static PPP_Messaging messaging_interface = {
164       &Messaging_HandleMessage,
165     };
166     return &messaging_interface;
167   }
168   return NULL;
169 }
170
171 PP_EXPORT void PPP_ShutdownModule() {}