| /* Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| /** @file debugging.c |
| * This example, is a modified version of hello world. It will start a second |
| * thread and cause that thread to crash via a NULL dereference. |
| */ |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include "ppapi/c/pp_errors.h" |
| #include "ppapi/c/pp_module.h" |
| #include "ppapi/c/pp_var.h" |
| #include "ppapi/c/ppb.h" |
| #include "ppapi/c/ppb_core.h" |
| #include "ppapi/c/ppb_instance.h" |
| #include "ppapi/c/ppb_messaging.h" |
| #include "ppapi/c/ppb_var.h" |
| #include "ppapi/c/ppp.h" |
| #include "ppapi/c/ppp_instance.h" |
| #include "ppapi/c/ppp_messaging.h" |
| |
| #include <pthread.h> |
| |
| #include "error_handling/error_handling.h" |
| |
| PPB_Messaging* ppb_messaging_interface = NULL; |
| PPB_Var* ppb_var_interface = NULL; |
| PPB_Core* ppb_core_interface = NULL; |
| |
| pthread_t g_NexeThread; |
| pthread_t g_PPAPIThread; |
| PP_Instance g_Instance; |
| |
| volatile int g_CrashTime = 0; |
| |
| void PostMessage(const char* str); |
| |
| void layer5(int x, int y) { |
| if (g_CrashTime) { |
| *(volatile int*)x = y; |
| } |
| } |
| |
| void layer4(int x) { layer5(x, 1); } |
| |
| void layer3(int a, int b, int c) { layer4(a + b + c); } |
| |
| void layer2(int i, int j) { layer3(i, j, 7); } |
| |
| void layer1(int s, int t) { |
| int* junk = (int*)alloca(sizeof(int) * 1234); |
| junk[0] = s + 5; |
| layer2(junk[0], t + 1); |
| } |
| |
| void* NexeMain(void* data) { |
| PostMessage("Running Boom thread."); |
| while (1) { |
| layer1(2, 9); |
| } |
| return NULL; |
| } |
| |
| void PostMessage(const char* str) { |
| if (NULL == str) |
| return; |
| if (NULL == ppb_messaging_interface) |
| return; |
| if (0 == g_Instance) |
| return; |
| |
| fprintf(stdout, "%s\n", str); |
| fflush(stdout); |
| |
| if (ppb_var_interface != NULL) { |
| struct PP_Var var = ppb_var_interface->VarFromUtf8(str, strlen(str)); |
| ppb_messaging_interface->PostMessage(g_Instance, var); |
| ppb_var_interface->Release(var); |
| } |
| } |
| |
| void DumpJson(const char* json) { |
| const char kTrcPrefix[] = "TRC: "; |
| size_t size = sizeof(kTrcPrefix) + strlen(json) + 1; // +1 for NULL. |
| char* out = (char*)malloc(size); |
| strcpy(out, kTrcPrefix); |
| strcat(out, json); |
| |
| PostMessage(out); |
| free(out); |
| } |
| |
| static PP_Bool Instance_DidCreate(PP_Instance instance, |
| uint32_t argc, |
| const char* argn[], |
| const char* argv[]) { |
| g_Instance = instance; |
| g_PPAPIThread = pthread_self(); |
| |
| PostMessage("LOG: DidCreate"); |
| |
| /* Request exception callbacks with JSON. */ |
| EHRequestExceptionsJson(DumpJson); |
| |
| /* Report back if the request was honored. */ |
| if (!EHHanderInstalled()) { |
| PostMessage("LOG: Stack traces not available, so don't expect them.\n"); |
| } else { |
| PostMessage("LOG: Stack traces are on."); |
| } |
| pthread_create(&g_NexeThread, NULL, NexeMain, NULL); |
| return PP_TRUE; |
| } |
| |
| static void Instance_DidDestroy(PP_Instance instance) {} |
| |
| static void Instance_DidChangeView(PP_Instance instance, |
| PP_Resource view_resource) {} |
| |
| static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {} |
| |
| static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance, |
| PP_Resource url_loader) { |
| return PP_FALSE; |
| } |
| |
| /** |
| * Handles message from JavaScript. |
| * |
| * Any message from JS is a request to cause the main thread to crash. |
| */ |
| static void Messaging_HandleMessage(PP_Instance instance, |
| struct PP_Var message) { |
| PostMessage("LOG: Got BOOM"); |
| g_CrashTime = 1; |
| } |
| |
| PP_EXPORT int32_t |
| PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface get_browser) { |
| ppb_messaging_interface = |
| (PPB_Messaging*)(get_browser(PPB_MESSAGING_INTERFACE)); |
| ppb_var_interface = (PPB_Var*)(get_browser(PPB_VAR_INTERFACE)); |
| ppb_core_interface = (PPB_Core*)(get_browser(PPB_CORE_INTERFACE)); |
| return PP_OK; |
| } |
| |
| PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { |
| if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) { |
| static PPP_Instance instance_interface = { |
| &Instance_DidCreate, |
| &Instance_DidDestroy, |
| &Instance_DidChangeView, |
| &Instance_DidChangeFocus, |
| &Instance_HandleDocumentLoad, |
| }; |
| return &instance_interface; |
| } |
| if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) { |
| static PPP_Messaging messaging_interface = { |
| &Messaging_HandleMessage, |
| }; |
| return &messaging_interface; |
| } |
| return NULL; |
| } |
| |
| PP_EXPORT void PPP_ShutdownModule() {} |