15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)/** @file debugging.c
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This example, is a modified version of hello world.  It will start a second
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * thread and cause that thread to crash via a NULL dereference.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_module.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_var.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_core.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_instance.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_messaging.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_var.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppp.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppp_instance.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppp_messaging.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pthread.h>
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "error_handling/error_handling.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Messaging* ppb_messaging_interface = NULL;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Var* ppb_var_interface = NULL;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPB_Core* ppb_core_interface = NULL;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pthread_t g_NexeThread;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)pthread_t g_PPAPIThread;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Instance g_Instance;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)volatile int g_CrashTime = 0;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PostMessage(const char* str);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void layer5(int x, int y) {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_CrashTime) {
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *(volatile int*)x = y;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void layer4(int x) { layer5(x, 1); }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void layer3(int a, int b, int c) { layer4(a + b + c); }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void layer2(int i, int j) { layer3(i, j, 7); }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void layer1(int s, int t) {
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int* junk = (int*)alloca(sizeof(int) * 1234);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  junk[0] = s + 5;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layer2(junk[0], t + 1);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void* NexeMain(void* data) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PostMessage("Running Boom thread.");
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (1) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layer1(2, 9);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void PostMessage(const char* str) {
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (NULL == str)
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (NULL == ppb_messaging_interface)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (0 == g_Instance)
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  fprintf(stdout, "%s\n", str);
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  fflush(stdout);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (ppb_var_interface != NULL) {
804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    struct PP_Var var = ppb_var_interface->VarFromUtf8(str, strlen(str));
814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ppb_messaging_interface->PostMessage(g_Instance, var);
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ppb_var_interface->Release(var);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DumpJson(const char* json) {
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const char kTrcPrefix[] = "TRC: ";
884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  size_t size = sizeof(kTrcPrefix) + strlen(json) + 1;  // +1 for NULL.
894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  char* out = (char*)malloc(size);
904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  strcpy(out, kTrcPrefix);
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  strcat(out, json);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PostMessage(out);
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  free(out);
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PP_Bool Instance_DidCreate(PP_Instance instance,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  uint32_t argc,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const char* argn[],
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const char* argv[]) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_Instance = instance;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_PPAPIThread = pthread_self();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PostMessage("LOG: DidCreate");
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /* Request exception callbacks with JSON. */
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EHRequestExceptionsJson(DumpJson);
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /* Report back if the request was honored. */
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!EHHanderInstalled()) {
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PostMessage("LOG: Stack traces not available, so don't expect them.\n");
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    PostMessage("LOG: Stack traces are on.");
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pthread_create(&g_NexeThread, NULL, NexeMain, NULL);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_TRUE;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void Instance_DidDestroy(PP_Instance instance) {}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void Instance_DidChangeView(PP_Instance instance,
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   PP_Resource view_resource) {}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           PP_Resource url_loader) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_FALSE;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handles message from JavaScript.
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Any message from JS is a request to cause the main thread to crash.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void Messaging_HandleMessage(PP_Instance instance,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    struct PP_Var message) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PostMessage("LOG: Got BOOM");
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_CrashTime = 1;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)PP_EXPORT int32_t
1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface get_browser) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppb_messaging_interface =
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (PPB_Messaging*)(get_browser(PPB_MESSAGING_INTERFACE));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppb_var_interface = (PPB_Var*)(get_browser(PPB_VAR_INTERFACE));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppb_core_interface = (PPB_Core*)(get_browser(PPB_CORE_INTERFACE));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_EXPORT const void* PPP_GetInterface(const char* interface_name) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) {
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static PPP_Instance instance_interface = {
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        &Instance_DidCreate,
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        &Instance_DidDestroy,
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        &Instance_DidChangeView,
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        &Instance_DidChangeFocus,
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        &Instance_HandleDocumentLoad,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &instance_interface;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static PPP_Messaging messaging_interface = {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &Messaging_HandleMessage,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &messaging_interface;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PP_EXPORT void PPP_ShutdownModule() {}
172