Skip to content

Commit 20303f8

Browse files
committed
Next phase of the move, reformat use C++ features.
Use the libbacktrace C++ interface instead of the C interface in debuggerd. Reformat the debuggerd code to be closer to Google C++ style. Fix all debuggerd casts to be C++ casts. Add a frame number to the frame data structure for ease of formatting and add another FormatFrameData function. Change the format_test to use the new FormatFrameData function. Modify all of the backtrace_test to use the C++ interface. Change-Id: I10e1610861acf7f4a3ad53276b74971cfbfda464
1 parent e76343e commit 20303f8

File tree

17 files changed

+1812
-1925
lines changed

17 files changed

+1812
-1925
lines changed

debuggerd/arm/machine.cpp

Lines changed: 133 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
1-
/* system/debuggerd/debuggerd.c
2-
**
3-
** Copyright 2006, The Android Open Source Project
4-
**
5-
** Licensed under the Apache License, Version 2.0 (the "License");
6-
** you may not use this file except in compliance with the License.
7-
** You may obtain a copy of the License at
8-
**
9-
** http://www.apache.org/licenses/LICENSE-2.0
10-
**
11-
** Unless required by applicable law or agreed to in writing, software
12-
** distributed under the License is distributed on an "AS IS" BASIS,
13-
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14-
** See the License for the specific language governing permissions and
15-
** limitations under the License.
16-
*/
1+
/*
2+
*
3+
* Copyright 2006, The Android Open Source Project
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
1717

1818
#include <errno.h>
19-
#include <stdbool.h>
2019
#include <stddef.h>
2120
#include <stdio.h>
2221
#include <stdlib.h>
@@ -28,7 +27,7 @@
2827
#include "../utility.h"
2928
#include "../machine.h"
3029

31-
/* enable to dump memory pointed to by every register */
30+
// enable to dump memory pointed to by every register
3231
#define DUMP_MEMORY_FOR_ALL_REGISTERS 1
3332

3433
#ifdef WITH_VFP
@@ -40,140 +39,134 @@
4039
#endif
4140

4241
static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scope_flags) {
43-
char code_buffer[64]; /* actual 8+1+((8+1)*4) + 1 == 45 */
44-
char ascii_buffer[32]; /* actual 16 + 1 == 17 */
45-
uintptr_t p, end;
46-
47-
p = addr & ~3;
48-
p -= 32;
49-
if (p > addr) {
50-
/* catch underflow */
51-
p = 0;
52-
}
53-
/* Dump more memory content for the crashing thread. */
54-
end = p + 256;
55-
/* catch overflow; 'end - p' has to be multiples of 16 */
56-
while (end < p)
57-
end -= 16;
58-
59-
/* Dump the code around PC as:
60-
* addr contents ascii
61-
* 00008d34 ef000000 e8bd0090 e1b00000 512fff1e ............../Q
62-
* 00008d44 ea00b1f9 e92d0090 e3a070fc ef000000 ......-..p......
63-
*/
64-
while (p < end) {
65-
char* asc_out = ascii_buffer;
66-
67-
sprintf(code_buffer, "%08x ", p);
68-
69-
int i;
70-
for (i = 0; i < 4; i++) {
71-
/*
72-
* If we see (data == -1 && errno != 0), we know that the ptrace
73-
* call failed, probably because we're dumping memory in an
74-
* unmapped or inaccessible page. I don't know if there's
75-
* value in making that explicit in the output -- it likely
76-
* just complicates parsing and clarifies nothing for the
77-
* enlightened reader.
78-
*/
79-
long data = ptrace(PTRACE_PEEKTEXT, tid, (void*)p, NULL);
80-
sprintf(code_buffer + strlen(code_buffer), "%08lx ", data);
81-
82-
/* Enable the following code blob to dump ASCII values */
42+
char code_buffer[64]; // actual 8+1+((8+1)*4) + 1 == 45
43+
char ascii_buffer[32]; // actual 16 + 1 == 17
44+
uintptr_t p, end;
45+
46+
p = addr & ~3;
47+
p -= 32;
48+
if (p > addr) {
49+
// catch underflow
50+
p = 0;
51+
}
52+
// Dump more memory content for the crashing thread.
53+
end = p + 256;
54+
// catch overflow; 'end - p' has to be multiples of 16
55+
while (end < p)
56+
end -= 16;
57+
58+
// Dump the code around PC as:
59+
// addr contents ascii
60+
// 00008d34 ef000000 e8bd0090 e1b00000 512fff1e ............../Q
61+
// 00008d44 ea00b1f9 e92d0090 e3a070fc ef000000 ......-..p......
62+
while (p < end) {
63+
char* asc_out = ascii_buffer;
64+
65+
sprintf(code_buffer, "%08x ", p);
66+
67+
int i;
68+
for (i = 0; i < 4; i++) {
69+
// If we see (data == -1 && errno != 0), we know that the ptrace
70+
// call failed, probably because we're dumping memory in an
71+
// unmapped or inaccessible page. I don't know if there's
72+
// value in making that explicit in the output -- it likely
73+
// just complicates parsing and clarifies nothing for the
74+
// enlightened reader.
75+
long data = ptrace(PTRACE_PEEKTEXT, tid, reinterpret_cast<void*>(p), NULL);
76+
sprintf(code_buffer + strlen(code_buffer), "%08lx ", data);
77+
78+
// Enable the following code blob to dump ASCII values
8379
#if 0
84-
int j;
85-
for (j = 0; j < 4; j++) {
86-
/*
87-
* Our isprint() allows high-ASCII characters that display
88-
* differently (often badly) in different viewers, so we
89-
* just use a simpler test.
90-
*/
91-
char val = (data >> (j*8)) & 0xff;
92-
if (val >= 0x20 && val < 0x7f) {
93-
*asc_out++ = val;
94-
} else {
95-
*asc_out++ = '.';
96-
}
97-
}
98-
#endif
99-
p += 4;
80+
int j;
81+
for (j = 0; j < 4; j++) {
82+
// Our isprint() allows high-ASCII characters that display
83+
// differently (often badly) in different viewers, so we
84+
// just use a simpler test.
85+
char val = (data >> (j*8)) & 0xff;
86+
if (val >= 0x20 && val < 0x7f) {
87+
*asc_out++ = val;
88+
} else {
89+
*asc_out++ = '.';
10090
}
101-
*asc_out = '\0';
102-
_LOG(log, scope_flags, " %s %s\n", code_buffer, ascii_buffer);
91+
}
92+
#endif
93+
p += 4;
10394
}
95+
*asc_out = '\0';
96+
_LOG(log, scope_flags, " %s %s\n", code_buffer, ascii_buffer);
97+
}
10498
}
10599

106-
/*
107-
* If configured to do so, dump memory around *all* registers
108-
* for the crashing thread.
109-
*/
100+
// If configured to do so, dump memory around *all* registers
101+
// for the crashing thread.
110102
void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
111-
struct pt_regs regs;
112-
if(ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
113-
return;
103+
struct pt_regs regs;
104+
if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
105+
return;
106+
}
107+
108+
if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
109+
static const char REG_NAMES[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp";
110+
111+
for (int reg = 0; reg < 14; reg++) {
112+
// this may not be a valid way to access, but it'll do for now
113+
uintptr_t addr = regs.uregs[reg];
114+
115+
// Don't bother if it looks like a small int or ~= null, or if
116+
// it's in the kernel area.
117+
if (addr < 4096 || addr >= 0xc0000000) {
118+
continue;
119+
}
120+
121+
_LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
122+
dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
114123
}
124+
}
115125

116-
if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
117-
static const char REG_NAMES[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp";
126+
// explicitly allow upload of code dump logging
127+
_LOG(log, scope_flags, "\ncode around pc:\n");
128+
dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc), scope_flags);
118129

119-
for (int reg = 0; reg < 14; reg++) {
120-
/* this may not be a valid way to access, but it'll do for now */
121-
uintptr_t addr = regs.uregs[reg];
122-
123-
/*
124-
* Don't bother if it looks like a small int or ~= null, or if
125-
* it's in the kernel area.
126-
*/
127-
if (addr < 4096 || addr >= 0xc0000000) {
128-
continue;
129-
}
130-
131-
_LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
132-
dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
133-
}
134-
}
135-
136-
/* explicitly allow upload of code dump logging */
137-
_LOG(log, scope_flags, "\ncode around pc:\n");
138-
dump_memory(log, tid, (uintptr_t)regs.ARM_pc, scope_flags);
139-
140-
if (regs.ARM_pc != regs.ARM_lr) {
141-
_LOG(log, scope_flags, "\ncode around lr:\n");
142-
dump_memory(log, tid, (uintptr_t)regs.ARM_lr, scope_flags);
143-
}
130+
if (regs.ARM_pc != regs.ARM_lr) {
131+
_LOG(log, scope_flags, "\ncode around lr:\n");
132+
dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr), scope_flags);
133+
}
144134
}
145135

146-
void dump_registers(log_t* log, pid_t tid, int scope_flags)
147-
{
148-
struct pt_regs r;
149-
if(ptrace(PTRACE_GETREGS, tid, 0, &r)) {
150-
_LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
151-
return;
152-
}
153-
154-
_LOG(log, scope_flags, " r0 %08x r1 %08x r2 %08x r3 %08x\n",
155-
(uint32_t)r.ARM_r0, (uint32_t)r.ARM_r1, (uint32_t)r.ARM_r2, (uint32_t)r.ARM_r3);
156-
_LOG(log, scope_flags, " r4 %08x r5 %08x r6 %08x r7 %08x\n",
157-
(uint32_t)r.ARM_r4, (uint32_t)r.ARM_r5, (uint32_t)r.ARM_r6, (uint32_t)r.ARM_r7);
158-
_LOG(log, scope_flags, " r8 %08x r9 %08x sl %08x fp %08x\n",
159-
(uint32_t)r.ARM_r8, (uint32_t)r.ARM_r9, (uint32_t)r.ARM_r10, (uint32_t)r.ARM_fp);
160-
_LOG(log, scope_flags, " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n",
161-
(uint32_t)r.ARM_ip, (uint32_t)r.ARM_sp, (uint32_t)r.ARM_lr,
162-
(uint32_t)r.ARM_pc, (uint32_t)r.ARM_cpsr);
136+
void dump_registers(log_t* log, pid_t tid, int scope_flags) {
137+
struct pt_regs r;
138+
if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
139+
_LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
140+
return;
141+
}
142+
143+
_LOG(log, scope_flags, " r0 %08x r1 %08x r2 %08x r3 %08x\n",
144+
static_cast<uint32_t>(r.ARM_r0), static_cast<uint32_t>(r.ARM_r1),
145+
static_cast<uint32_t>(r.ARM_r2), static_cast<uint32_t>(r.ARM_r3));
146+
_LOG(log, scope_flags, " r4 %08x r5 %08x r6 %08x r7 %08x\n",
147+
static_cast<uint32_t>(r.ARM_r4), static_cast<uint32_t>(r.ARM_r5),
148+
static_cast<uint32_t>(r.ARM_r6), static_cast<uint32_t>(r.ARM_r7));
149+
_LOG(log, scope_flags, " r8 %08x r9 %08x sl %08x fp %08x\n",
150+
static_cast<uint32_t>(r.ARM_r8), static_cast<uint32_t>(r.ARM_r9),
151+
static_cast<uint32_t>(r.ARM_r10), static_cast<uint32_t>(r.ARM_fp));
152+
_LOG(log, scope_flags, " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n",
153+
static_cast<uint32_t>(r.ARM_ip), static_cast<uint32_t>(r.ARM_sp),
154+
static_cast<uint32_t>(r.ARM_lr), static_cast<uint32_t>(r.ARM_pc),
155+
static_cast<uint32_t>(r.ARM_cpsr));
163156

164157
#ifdef WITH_VFP
165-
struct user_vfp vfp_regs;
166-
int i;
167-
168-
if(ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) {
169-
_LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
170-
return;
171-
}
172-
173-
for (i = 0; i < NUM_VFP_REGS; i += 2) {
174-
_LOG(log, scope_flags, " d%-2d %016llx d%-2d %016llx\n",
175-
i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]);
176-
}
177-
_LOG(log, scope_flags, " scr %08lx\n", vfp_regs.fpscr);
158+
struct user_vfp vfp_regs;
159+
int i;
160+
161+
if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) {
162+
_LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
163+
return;
164+
}
165+
166+
for (i = 0; i < NUM_VFP_REGS; i += 2) {
167+
_LOG(log, scope_flags, " d%-2d %016llx d%-2d %016llx\n",
168+
i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]);
169+
}
170+
_LOG(log, scope_flags, " scr %08lx\n", vfp_regs.fpscr);
178171
#endif
179172
}

0 commit comments

Comments
 (0)