debugging.c revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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 30PPB_Messaging* ppb_messaging_interface = NULL; 31PPB_Var* ppb_var_interface = NULL; 32PPB_Core* ppb_core_interface = NULL; 33 34pthread_t g_NexeThread; 35pthread_t g_PPAPIThread; 36PP_Instance g_Instance; 37 38volatile int g_CrashTime = 0; 39 40void PostMessage(const char* str); 41 42void layer5(int x, int y) { 43 if (g_CrashTime) { 44 *(volatile int*)x = y; 45 } 46} 47 48void layer4(int x) { layer5(x, 1); } 49 50void layer3(int a, int b, int c) { layer4(a + b + c); } 51 52void layer2(int i, int j) { layer3(i, j, 7); } 53 54void 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 60void* NexeMain(void* data) { 61 PostMessage("Running Boom thread."); 62 while (1) { 63 layer1(2, 9); 64 } 65 return NULL; 66} 67 68void 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 86void 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 97static 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 119static void Instance_DidDestroy(PP_Instance instance) {} 120 121static void Instance_DidChangeView(PP_Instance instance, 122 PP_Resource view_resource) {} 123 124static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {} 125 126static 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 */ 136static void Messaging_HandleMessage(PP_Instance instance, 137 struct PP_Var message) { 138 PostMessage("LOG: Got BOOM"); 139 g_CrashTime = 1; 140} 141 142PP_EXPORT int32_t 143PPP_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 151PP_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 171PP_EXPORT void PPP_ShutdownModule() {} 172