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