Debug.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /*
  2. * Copyright (C) 2005 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <hwbinder/Debug.h>
  17. #include <hwbinder/ProcessState.h>
  18. #include <utils/misc.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <ctype.h>
  22. namespace android {
  23. namespace hardware {
  24. // ---------------------------------------------------------------------
  25. static const char indentStr[] =
  26. " "
  27. " ";
  28. const char* stringForIndent(int32_t indentLevel)
  29. {
  30. ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
  31. return indentStr + (off < 0 ? 0 : off);
  32. }
  33. // ---------------------------------------------------------------------
  34. static void defaultPrintFunc(void* /*cookie*/, const char* txt)
  35. {
  36. printf("%s", txt);
  37. }
  38. // ---------------------------------------------------------------------
  39. static inline int isident(int c)
  40. {
  41. return isalnum(c) || c == '_';
  42. }
  43. static inline bool isasciitype(char c)
  44. {
  45. if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
  46. return false;
  47. }
  48. static inline char makehexdigit(uint32_t val)
  49. {
  50. return "0123456789abcdef"[val&0xF];
  51. }
  52. static char* appendhexnum(uint32_t val, char* out)
  53. {
  54. for( int32_t i=28; i>=0; i-=4 ) {
  55. *out++ = makehexdigit( val>>i );
  56. }
  57. *out = 0;
  58. return out;
  59. }
  60. static char* appendcharornum(char c, char* out, bool skipzero = true)
  61. {
  62. if (skipzero && c == 0) return out;
  63. if (isasciitype(c)) {
  64. *out++ = c;
  65. return out;
  66. }
  67. *out++ = '\\';
  68. *out++ = 'x';
  69. *out++ = makehexdigit(c>>4);
  70. *out++ = makehexdigit(c);
  71. return out;
  72. }
  73. static char* typetostring(uint32_t type, char* out,
  74. bool fullContext = true,
  75. bool strict = false)
  76. {
  77. char* pos = out;
  78. char c[4];
  79. c[0] = (char)((type>>24)&0xFF);
  80. c[1] = (char)((type>>16)&0xFF);
  81. c[2] = (char)((type>>8)&0xFF);
  82. c[3] = (char)(type&0xFF);
  83. bool valid;
  84. if( !strict ) {
  85. // now even less strict!
  86. // valid = isasciitype(c[3]);
  87. valid = true;
  88. int32_t i = 0;
  89. bool zero = true;
  90. while (valid && i<3) {
  91. if (c[i] == 0) {
  92. if (!zero) valid = false;
  93. } else {
  94. zero = false;
  95. //if (!isasciitype(c[i])) valid = false;
  96. }
  97. i++;
  98. }
  99. // if all zeros, not a valid type code.
  100. if (zero) valid = false;
  101. } else {
  102. valid = isident(c[3]) ? true : false;
  103. int32_t i = 0;
  104. bool zero = true;
  105. while (valid && i<3) {
  106. if (c[i] == 0) {
  107. if (!zero) valid = false;
  108. } else {
  109. zero = false;
  110. if (!isident(c[i])) valid = false;
  111. }
  112. i++;
  113. }
  114. }
  115. if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
  116. if( fullContext ) *pos++ = '\'';
  117. pos = appendcharornum(c[0], pos);
  118. pos = appendcharornum(c[1], pos);
  119. pos = appendcharornum(c[2], pos);
  120. pos = appendcharornum(c[3], pos);
  121. if( fullContext ) *pos++ = '\'';
  122. *pos = 0;
  123. return pos;
  124. }
  125. if( fullContext ) {
  126. *pos++ = '0';
  127. *pos++ = 'x';
  128. }
  129. return appendhexnum(type, pos);
  130. }
  131. void printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
  132. {
  133. char buffer[32];
  134. char* end = typetostring(typeCode, buffer);
  135. *end = 0;
  136. func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
  137. }
  138. void printHexData(int32_t indent, const void *buf, size_t length,
  139. size_t bytesPerLine, int32_t singleLineBytesCutoff,
  140. size_t alignment, bool cStyle,
  141. debugPrintFunc func, void* cookie)
  142. {
  143. if (alignment == 0) {
  144. if (bytesPerLine >= 16) alignment = 4;
  145. else if (bytesPerLine >= 8) alignment = 2;
  146. else alignment = 1;
  147. }
  148. if (func == nullptr) func = defaultPrintFunc;
  149. size_t offset;
  150. unsigned char *pos = (unsigned char *)buf;
  151. if (pos == nullptr) {
  152. if (singleLineBytesCutoff < 0) func(cookie, "\n");
  153. func(cookie, "(NULL)");
  154. return;
  155. }
  156. if (length == 0) {
  157. if (singleLineBytesCutoff < 0) func(cookie, "\n");
  158. func(cookie, "(empty)");
  159. return;
  160. }
  161. if ((int32_t)length < 0) {
  162. if (singleLineBytesCutoff < 0) func(cookie, "\n");
  163. char buf[64];
  164. sprintf(buf, "(bad length: %zu)", length);
  165. func(cookie, buf);
  166. return;
  167. }
  168. char buffer[256];
  169. static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
  170. if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
  171. const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
  172. bool newLine = false;
  173. if (cStyle) {
  174. indent++;
  175. func(cookie, "{\n");
  176. newLine = true;
  177. } else if (!oneLine) {
  178. func(cookie, "\n");
  179. newLine = true;
  180. }
  181. for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
  182. long remain = length;
  183. char* c = buffer;
  184. if (!oneLine && !cStyle) {
  185. sprintf(c, "0x%08x: ", (int)offset);
  186. c += 12;
  187. }
  188. size_t index;
  189. size_t word;
  190. for (word = 0; word < bytesPerLine; ) {
  191. size_t align_offset = alignment-(alignment?1:0);
  192. if (remain > 0 && (size_t)remain <= align_offset) {
  193. align_offset = remain - 1;
  194. }
  195. const size_t startIndex = word+align_offset;
  196. for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
  197. if (!cStyle) {
  198. if (index == 0 && word > 0 && alignment > 0) {
  199. *c++ = ' ';
  200. }
  201. if (remain-- > 0) {
  202. const unsigned char val = *(pos+startIndex-index);
  203. *c++ = makehexdigit(val>>4);
  204. *c++ = makehexdigit(val);
  205. } else if (!oneLine) {
  206. *c++ = ' ';
  207. *c++ = ' ';
  208. }
  209. } else {
  210. if (remain > 0) {
  211. if (index == 0 && word > 0) {
  212. *c++ = ',';
  213. *c++ = ' ';
  214. }
  215. if (index == 0) {
  216. *c++ = '0';
  217. *c++ = 'x';
  218. }
  219. const unsigned char val = *(pos+startIndex-index);
  220. *c++ = makehexdigit(val>>4);
  221. *c++ = makehexdigit(val);
  222. remain--;
  223. }
  224. }
  225. }
  226. word += index;
  227. }
  228. if (!cStyle) {
  229. remain = length;
  230. *c++ = ' ';
  231. *c++ = '\'';
  232. for (index = 0; index < bytesPerLine; index++) {
  233. if (remain-- > 0) {
  234. const unsigned char val = pos[index];
  235. *c++ = (val >= ' ' && val < 127) ? val : '.';
  236. } else if (!oneLine) {
  237. *c++ = ' ';
  238. }
  239. }
  240. *c++ = '\'';
  241. if (length > bytesPerLine) *c++ = '\n';
  242. } else {
  243. if (remain > 0) *c++ = ',';
  244. *c++ = '\n';
  245. }
  246. if (newLine && indent) func(cookie, stringForIndent(indent));
  247. *c = 0;
  248. func(cookie, buffer);
  249. newLine = true;
  250. if (length <= bytesPerLine) break;
  251. length -= bytesPerLine;
  252. }
  253. if (cStyle) {
  254. if (indent > 0) func(cookie, stringForIndent(indent-1));
  255. func(cookie, "};");
  256. }
  257. }
  258. ssize_t getHWBinderKernelReferences(size_t count, uintptr_t* buf) {
  259. sp<ProcessState> proc = ProcessState::selfOrNull();
  260. if (proc.get() == nullptr) {
  261. return 0;
  262. }
  263. return proc->getKernelReferences(count, buf);
  264. }
  265. }; // namespace hardware
  266. }; // namespace android