Debug.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $TOG: Debug.c /main/5 1998/04/06 13:32:19 mgreess $ */
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <unistd.h>
  27. #include <signal.h>
  28. #include <errno.h>
  29. #include <X11/Intrinsic.h>
  30. #include <X11/Xlibint.h>
  31. #define INT_MESSAGE3 "XIO: fatal IO error %d (%s) on X server \"%s\"\r\n"
  32. #define INT_MESSAGE4 " after %lu requests (%lu known processed) with %d events remaining.\r\n"
  33. #define INT_MESSAGE5 " The connection was probably broken by a server shudown or KillClient.\r\n"
  34. static int PrintXError(Display *dpy, XErrorEvent *event, FILE *fp);
  35. static const char *SysErrorMsg(int n);
  36. /* Error Handlers */
  37. static int XIOError(Display *dpy);
  38. static int XError(Display *dpy, XErrorEvent *event);
  39. static void _XtError(String);
  40. static Boolean G_DumpCore;
  41. void
  42. Debug(
  43. XtAppContext app_context
  44. )
  45. {
  46. XSetErrorHandler(XError);
  47. XSetIOErrorHandler(XIOError);
  48. XtAppSetErrorHandler(app_context, _XtError);
  49. G_DumpCore = True;
  50. }
  51. /*
  52. * NAME: XError
  53. * FUNCTION:
  54. * RETURNS:
  55. */
  56. static int
  57. XError(
  58. Display *dpy,
  59. XErrorEvent *event
  60. )
  61. {
  62. if (PrintXError(dpy, event, stderr) == 0)
  63. return 0;
  64. if (G_DumpCore)
  65. kill(getpid(), SIGQUIT);
  66. else
  67. exit(1);
  68. }
  69. /*
  70. * NAME: XIOError
  71. * FUNCTION:
  72. * RETURNS:
  73. */
  74. static int
  75. XIOError(
  76. Display *dpy
  77. )
  78. {
  79. fprintf(stderr, INT_MESSAGE3,
  80. errno, SysErrorMsg (errno), DisplayString (dpy));
  81. fprintf(stderr, INT_MESSAGE4,
  82. NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy), QLength(dpy));
  83. if (errno == EPIPE)
  84. fprintf(stderr, INT_MESSAGE5);
  85. if (G_DumpCore)
  86. kill(getpid(), SIGQUIT);
  87. else
  88. exit(1);
  89. }
  90. /*
  91. * NAME: SysErrorMsg
  92. * FUNCTION:
  93. * RETURNS:
  94. */
  95. static const char *
  96. SysErrorMsg(
  97. int n
  98. )
  99. {
  100. return strerror(n);
  101. }
  102. /*
  103. * NAME: PrintXError
  104. * FUNCTION:
  105. * RETURNS:
  106. */
  107. static int
  108. PrintXError(
  109. Display *dpy,
  110. XErrorEvent *event,
  111. FILE *fp
  112. )
  113. {
  114. char buffer[BUFSIZ];
  115. char mesg[BUFSIZ];
  116. char number[32];
  117. char *mtype = "XlibMessage";
  118. _XExtension *ext = (_XExtension *)NULL;
  119. _XExtension *bext = (_XExtension *)NULL;
  120. XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
  121. XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
  122. fprintf(fp, "%s: %s\n ", mesg, buffer);
  123. XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
  124. mesg, BUFSIZ);
  125. fprintf(fp, mesg, event->request_code);
  126. if (event->request_code < 128)
  127. {
  128. sprintf(number, "%d", event->request_code);
  129. XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
  130. }
  131. else
  132. {
  133. for (ext = dpy->ext_procs;
  134. ext && (ext->codes.major_opcode != event->request_code);
  135. ext = ext->next)
  136. ;
  137. if (ext)
  138. snprintf(buffer, sizeof(buffer), "%s", ext->name);
  139. else
  140. buffer[0] = '\0';
  141. }
  142. fprintf(fp, " (%s)\n", buffer);
  143. if (event->request_code >= 128)
  144. {
  145. XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
  146. mesg, BUFSIZ);
  147. fputs(" ", fp);
  148. fprintf(fp, mesg, event->minor_code);
  149. if (ext)
  150. {
  151. sprintf(mesg, "%s.%d", ext->name, event->minor_code);
  152. XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
  153. fprintf(fp, " (%s)", buffer);
  154. }
  155. fputs("\n", fp);
  156. }
  157. if (event->error_code >= 128)
  158. {
  159. /* kludge, try to find the extension that caused it */
  160. buffer[0] = '\0';
  161. for (ext = dpy->ext_procs; ext; ext = ext->next)
  162. {
  163. if (ext->error_string)
  164. (*ext->error_string)(dpy, event->error_code, &ext->codes,
  165. buffer, BUFSIZ);
  166. if (buffer[0])
  167. {
  168. bext = ext;
  169. break;
  170. }
  171. if (ext->codes.first_error &&
  172. ext->codes.first_error < (int)event->error_code &&
  173. (!bext || ext->codes.first_error > bext->codes.first_error))
  174. bext = ext;
  175. }
  176. if (bext)
  177. sprintf(buffer, "%s.%d", bext->name,
  178. event->error_code - bext->codes.first_error);
  179. else
  180. strcpy(buffer, "Value");
  181. XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
  182. if (mesg[0])
  183. {
  184. fputs(" ", fp);
  185. fprintf(fp, mesg, event->resourceid);
  186. fputs("\n", fp);
  187. }
  188. /* let extensions try to print the values */
  189. for (ext = dpy->ext_procs; ext; ext = ext->next)
  190. {
  191. if (ext->error_values)
  192. (*ext->error_values)(dpy, event, fp);
  193. }
  194. }
  195. else if ((event->error_code == BadWindow) ||
  196. (event->error_code == BadPixmap) ||
  197. (event->error_code == BadCursor) ||
  198. (event->error_code == BadFont) ||
  199. (event->error_code == BadDrawable) ||
  200. (event->error_code == BadColor) ||
  201. (event->error_code == BadGC) ||
  202. (event->error_code == BadIDChoice) ||
  203. (event->error_code == BadValue) ||
  204. (event->error_code == BadAtom))
  205. {
  206. if (event->error_code == BadValue)
  207. XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%lx",
  208. mesg, BUFSIZ);
  209. else if (event->error_code == BadAtom)
  210. XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%lx",
  211. mesg, BUFSIZ);
  212. else
  213. XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%lx",
  214. mesg, BUFSIZ);
  215. fputs(" ", fp);
  216. fprintf(fp, mesg, event->resourceid);
  217. fputs("\n", fp);
  218. }
  219. XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%ld",
  220. mesg, BUFSIZ);
  221. fputs(" ", fp);
  222. fprintf(fp, mesg, event->serial);
  223. XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%ld",
  224. mesg, BUFSIZ);
  225. fputs("\n ", fp);
  226. fprintf(fp, mesg, dpy->request);
  227. fputs("\n", fp);
  228. if (event->error_code == BadImplementation)
  229. return 0;
  230. return 1;
  231. }
  232. /*
  233. * NAME: XtError
  234. * FUNCTION:
  235. * RETURNS:
  236. */
  237. static void
  238. _XtError(
  239. String string
  240. )
  241. {
  242. (void)fprintf(stderr, "XtToolkit Error: %s\n", string);
  243. if (G_DumpCore)
  244. kill(getpid(), SIGQUIT);
  245. else
  246. exit(1);
  247. }