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() {} 172