1 // SPDX-License-Identifier: GPL-2.0
9 #include <linux/compiler.h>
10 #include <linux/kernel.h>
11 #include <linux/string.h>
12 #include <linux/zalloc.h>
17 #include "util/debug.h"
18 #include "util/callchain.h"
19 #include "util/symbol_conf.h"
20 #ifdef HAVE_LIBLLVM_SUPPORT
21 #include "util/llvm-c-helpers.h"
26 #include "subcmd/run-command.h"
28 /* If addr2line doesn't return data for 1 second then timeout. */
29 int addr2line_timeout_ms
= 1 * 1000;
30 bool srcline_full_filename
;
32 char *srcline__unknown
= (char *)"??:0";
34 static const char *srcline_dso_name(struct dso
*dso
)
38 if (dso__symsrc_filename(dso
))
39 dso_name
= dso__symsrc_filename(dso
);
41 dso_name
= dso__long_name(dso
);
43 if (dso_name
[0] == '[')
46 if (is_perf_pid_map_name(dso_name
))
52 static int inline_list__append(struct symbol
*symbol
, char *srcline
,
53 struct inline_node
*node
)
55 struct inline_list
*ilist
;
57 ilist
= zalloc(sizeof(*ilist
));
61 ilist
->symbol
= symbol
;
62 ilist
->srcline
= srcline
;
64 if (callchain_param
.order
== ORDER_CALLEE
)
65 list_add_tail(&ilist
->list
, &node
->val
);
67 list_add(&ilist
->list
, &node
->val
);
72 /* basename version that takes a const input string */
73 static const char *gnu_basename(const char *path
)
75 const char *base
= strrchr(path
, '/');
77 return base
? base
+ 1 : path
;
80 static char *srcline_from_fileline(const char *file
, unsigned int line
)
87 if (!srcline_full_filename
)
88 file
= gnu_basename(file
);
90 if (asprintf(&srcline
, "%s:%u", file
, line
) < 0)
96 static struct symbol
*new_inline_sym(struct dso
*dso
,
97 struct symbol
*base_sym
,
100 struct symbol
*inline_sym
;
101 char *demangled
= NULL
;
107 demangled
= dso__demangle_sym(dso
, 0, funcname
);
109 funcname
= demangled
;
112 if (base_sym
&& strcmp(funcname
, base_sym
->name
) == 0) {
113 /* reuse the real, existing symbol */
114 inline_sym
= base_sym
;
115 /* ensure that we don't alias an inlined symbol, which could
116 * lead to double frees in inline_node__delete
118 assert(!base_sym
->inlined
);
120 /* create a fake symbol for the inline frame */
121 inline_sym
= symbol__new(base_sym
? base_sym
->start
: 0,
122 base_sym
? (base_sym
->end
- base_sym
->start
) : 0,
123 base_sym
? base_sym
->binding
: 0,
124 base_sym
? base_sym
->type
: 0,
127 inline_sym
->inlined
= 1;
135 #define MAX_INLINE_NEST 1024
137 #ifdef HAVE_LIBLLVM_SUPPORT
139 static void free_llvm_inline_frames(struct llvm_a2l_frame
*inline_frames
,
142 if (inline_frames
!= NULL
) {
143 for (int i
= 0; i
< num_frames
; ++i
) {
144 zfree(&inline_frames
[i
].filename
);
145 zfree(&inline_frames
[i
].funcname
);
147 zfree(&inline_frames
);
151 static int addr2line(const char *dso_name
, u64 addr
,
152 char **file
, unsigned int *line
, struct dso
*dso
,
153 bool unwind_inlines
, struct inline_node
*node
,
156 struct llvm_a2l_frame
*inline_frames
= NULL
;
157 int num_frames
= llvm_addr2line(dso_name
, addr
, file
, line
,
158 node
&& unwind_inlines
, &inline_frames
);
160 if (num_frames
== 0 || !inline_frames
) {
161 /* Error, or we didn't want inlines. */
165 for (int i
= 0; i
< num_frames
; ++i
) {
166 struct symbol
*inline_sym
=
167 new_inline_sym(dso
, sym
, inline_frames
[i
].funcname
);
168 char *srcline
= NULL
;
170 if (inline_frames
[i
].filename
) {
172 srcline_from_fileline(inline_frames
[i
].filename
,
173 inline_frames
[i
].line
);
175 if (inline_list__append(inline_sym
, srcline
, node
) != 0) {
176 free_llvm_inline_frames(inline_frames
, num_frames
);
180 free_llvm_inline_frames(inline_frames
, num_frames
);
185 void dso__free_a2l(struct dso
*dso __maybe_unused
)
187 /* Nothing to free. */
190 #elif defined(HAVE_LIBBFD_SUPPORT)
193 * Implement addr2line using libbfd.
195 #define PACKAGE "perf"
203 const char *filename
;
204 const char *funcname
;
211 static int bfd_error(const char *string
)
215 errmsg
= bfd_errmsg(bfd_get_error());
219 pr_debug("%s: %s\n", string
, errmsg
);
221 pr_debug("%s\n", errmsg
);
226 static int slurp_symtab(bfd
*abfd
, struct a2l_data
*a2l
)
231 bfd_boolean dynamic
= FALSE
;
233 if ((bfd_get_file_flags(abfd
) & HAS_SYMS
) == 0)
234 return bfd_error(bfd_get_filename(abfd
));
236 storage
= bfd_get_symtab_upper_bound(abfd
);
238 storage
= bfd_get_dynamic_symtab_upper_bound(abfd
);
242 return bfd_error(bfd_get_filename(abfd
));
244 syms
= malloc(storage
);
246 symcount
= bfd_canonicalize_dynamic_symtab(abfd
, syms
);
248 symcount
= bfd_canonicalize_symtab(abfd
, syms
);
252 return bfd_error(bfd_get_filename(abfd
));
259 static void find_address_in_section(bfd
*abfd
, asection
*section
, void *data
)
263 struct a2l_data
*a2l
= data
;
269 #ifdef bfd_get_section_flags
270 flags
= bfd_get_section_flags(abfd
, section
);
272 flags
= bfd_section_flags(section
);
274 if ((flags
& SEC_ALLOC
) == 0)
278 #ifdef bfd_get_section_vma
279 vma
= bfd_get_section_vma(abfd
, section
);
281 vma
= bfd_section_vma(section
);
283 #ifdef bfd_get_section_size
284 size
= bfd_get_section_size(section
);
286 size
= bfd_section_size(section
);
289 if (pc
< vma
|| pc
>= vma
+ size
)
292 a2l
->found
= bfd_find_nearest_line(abfd
, section
, a2l
->syms
, pc
- vma
,
293 &a2l
->filename
, &a2l
->funcname
,
296 if (a2l
->filename
&& !strlen(a2l
->filename
))
297 a2l
->filename
= NULL
;
300 static struct a2l_data
*addr2line_init(const char *path
)
303 struct a2l_data
*a2l
= NULL
;
305 abfd
= bfd_openr(path
, NULL
);
309 if (!bfd_check_format(abfd
, bfd_object
))
312 a2l
= zalloc(sizeof(*a2l
));
317 a2l
->input
= strdup(path
);
318 if (a2l
->input
== NULL
)
321 if (slurp_symtab(abfd
, a2l
))
328 zfree((char **)&a2l
->input
);
335 static void addr2line_cleanup(struct a2l_data
*a2l
)
338 bfd_close(a2l
->abfd
);
339 zfree((char **)&a2l
->input
);
344 static int inline_list__append_dso_a2l(struct dso
*dso
,
345 struct inline_node
*node
,
348 struct a2l_data
*a2l
= dso__a2l(dso
);
349 struct symbol
*inline_sym
= new_inline_sym(dso
, sym
, a2l
->funcname
);
350 char *srcline
= NULL
;
353 srcline
= srcline_from_fileline(a2l
->filename
, a2l
->line
);
355 return inline_list__append(inline_sym
, srcline
, node
);
358 static int addr2line(const char *dso_name
, u64 addr
,
359 char **file
, unsigned int *line
, struct dso
*dso
,
360 bool unwind_inlines
, struct inline_node
*node
,
364 struct a2l_data
*a2l
= dso__a2l(dso
);
367 a2l
= addr2line_init(dso_name
);
368 dso__set_a2l(dso
, a2l
);
372 if (!symbol_conf
.disable_add2line_warn
)
373 pr_warning("addr2line_init failed for %s\n", dso_name
);
380 bfd_map_over_sections(a2l
->abfd
, find_address_in_section
, a2l
);
385 if (unwind_inlines
) {
388 if (node
&& inline_list__append_dso_a2l(dso
, node
, sym
))
391 while (bfd_find_inliner_info(a2l
->abfd
, &a2l
->filename
,
392 &a2l
->funcname
, &a2l
->line
) &&
393 cnt
++ < MAX_INLINE_NEST
) {
395 if (a2l
->filename
&& !strlen(a2l
->filename
))
396 a2l
->filename
= NULL
;
399 if (inline_list__append_dso_a2l(dso
, node
, sym
))
401 // found at least one inline frame
408 *file
= a2l
->filename
? strdup(a2l
->filename
) : NULL
;
418 void dso__free_a2l(struct dso
*dso
)
420 struct a2l_data
*a2l
= dso__a2l(dso
);
425 addr2line_cleanup(a2l
);
427 dso__set_a2l(dso
, NULL
);
430 #else /* HAVE_LIBBFD_SUPPORT */
432 static int filename_split(char *filename
, unsigned int *line_nr
)
436 sep
= strchr(filename
, '\n');
440 if (!strcmp(filename
, "??:0"))
443 sep
= strchr(filename
, ':');
446 *line_nr
= strtoul(sep
, NULL
, 0);
449 pr_debug("addr2line missing ':' in filename split\n");
453 static void addr2line_subprocess_cleanup(struct child_process
*a2l
)
455 if (a2l
->pid
!= -1) {
456 kill(a2l
->pid
, SIGKILL
);
457 finish_command(a2l
); /* ignore result, we don't care */
466 static struct child_process
*addr2line_subprocess_init(const char *addr2line_path
,
467 const char *binary_path
)
469 const char *argv
[] = {
470 addr2line_path
?: "addr2line",
472 "-a", "-i", "-f", NULL
474 struct child_process
*a2l
= zalloc(sizeof(*a2l
));
475 int start_command_status
= 0;
478 pr_err("Failed to allocate memory for addr2line");
488 start_command_status
= start_command(a2l
);
489 a2l
->argv
= NULL
; /* it's not used after start_command; avoid dangling pointers */
491 if (start_command_status
!= 0) {
492 pr_warning("could not start addr2line (%s) for %s: start_command return code %d\n",
493 addr2line_path
, binary_path
, start_command_status
);
494 addr2line_subprocess_cleanup(a2l
);
507 static enum a2l_style
addr2line_configure(struct child_process
*a2l
, const char *dso_name
)
510 static enum a2l_style style
;
518 if (write(a2l
->in
, ",\n", 2) != 2)
521 io__init(&io
, a2l
->out
, buf
, sizeof(buf
));
522 ch
= io__get_char(&io
);
527 pr_debug("Detected LLVM addr2line style\n");
528 } else if (ch
== '0') {
529 style
= GNU_BINUTILS
;
532 pr_debug("Detected binutils addr2line style\n");
534 if (!symbol_conf
.disable_add2line_warn
) {
538 io__getline(&io
, &output
, &output_len
);
539 pr_warning("%s %s: addr2line configuration failed\n",
541 pr_warning("\t%c%s", ch
, output
);
543 pr_debug("Unknown/broken addr2line style\n");
547 ch
= io__get_char(&io
);
553 /* Ignore SIGPIPE in the event addr2line exits. */
554 signal(SIGPIPE
, SIG_IGN
);
559 static int read_addr2line_record(struct io
*io
,
560 enum a2l_style style
,
561 const char *dso_name
,
566 unsigned int *line_nr
)
571 * 0 ==> sentinel (or other ill-formed) record read
572 * 1 ==> a genuine record read
576 unsigned int dummy_line_nr
= 0;
579 if (function
!= NULL
)
582 if (filename
!= NULL
)
589 * Read the first line. Without an error this will be:
590 * - for the first line an address like 0x1234,
591 * - the binutils sentinel 0x0000000000000000,
592 * - the llvm-addr2line the sentinel ',' character,
593 * - the function name line for an inlined function.
595 if (io__getline(io
, &line
, &line_len
) < 0 || !line_len
)
598 pr_debug("%s %s: addr2line read address for sentinel: %s", __func__
, dso_name
, line
);
599 if (style
== LLVM
&& line_len
== 2 && line
[0] == ',') {
600 /* Found the llvm-addr2line sentinel character. */
603 } else if (style
== GNU_BINUTILS
&& (!first
|| addr
!= 0)) {
604 int zero_count
= 0, non_zero_count
= 0;
606 * Check for binutils sentinel ignoring it for the case the
607 * requested address is 0.
610 /* A given address should always start 0x. */
611 if (line_len
>= 2 || line
[0] != '0' || line
[1] != 'x') {
612 for (size_t i
= 2; i
< line_len
; i
++) {
615 else if (line
[i
] != '\n')
618 if (!non_zero_count
) {
621 if (first
&& !zero_count
) {
622 /* Line was erroneous just '0x'. */
626 * Line was 0x0..0, the sentinel for binutils. Remove
627 * the function and filename lines.
631 ch
= io__get_char(io
);
632 } while (ch
> 0 && ch
!= '\n');
634 ch
= io__get_char(io
);
635 } while (ch
> 0 && ch
!= '\n');
640 /* Read the second function name line (if inline data then this is the first line). */
641 if (first
&& (io__getline(io
, &line
, &line_len
) < 0 || !line_len
))
644 pr_debug("%s %s: addr2line read line: %s", __func__
, dso_name
, line
);
645 if (function
!= NULL
)
646 *function
= strdup(strim(line
));
651 /* Read the third filename and line number line. */
652 if (io__getline(io
, &line
, &line_len
) < 0 || !line_len
)
655 pr_debug("%s %s: addr2line filename:number : %s", __func__
, dso_name
, line
);
656 if (filename_split(line
, line_nr
== NULL
? &dummy_line_nr
: line_nr
) == 0 &&
657 style
== GNU_BINUTILS
) {
662 if (filename
!= NULL
)
663 *filename
= strdup(line
);
672 if (function
!= NULL
)
674 if (filename
!= NULL
)
679 static int inline_list__append_record(struct dso
*dso
,
680 struct inline_node
*node
,
682 const char *function
,
683 const char *filename
,
684 unsigned int line_nr
)
686 struct symbol
*inline_sym
= new_inline_sym(dso
, sym
, function
);
688 return inline_list__append(inline_sym
, srcline_from_fileline(filename
, line_nr
), node
);
691 static int addr2line(const char *dso_name
, u64 addr
,
692 char **file
, unsigned int *line_nr
,
695 struct inline_node
*node
,
696 struct symbol
*sym __maybe_unused
)
698 struct child_process
*a2l
= dso__a2l(dso
);
699 char *record_function
= NULL
;
700 char *record_filename
= NULL
;
701 unsigned int record_line_nr
= 0;
702 int record_status
= -1;
704 size_t inline_count
= 0;
708 struct io io
= { .eof
= false };
709 enum a2l_style a2l_style
;
712 if (!filename__has_section(dso_name
, ".debug_line"))
716 addr2line_subprocess_init(symbol_conf
.addr2line_path
, dso_name
));
721 if (!symbol_conf
.disable_add2line_warn
)
722 pr_warning("%s %s: addr2line_subprocess_init failed\n", __func__
, dso_name
);
725 a2l_style
= addr2line_configure(a2l
, dso_name
);
726 if (a2l_style
== BROKEN
)
730 * Send our request and then *deliberately* send something that can't be
731 * interpreted as a valid address to ask addr2line about (namely,
732 * ","). This causes addr2line to first write out the answer to our
733 * request, in an unbounded/unknown number of records, and then to write
734 * out the lines "0x0...0", "??" and "??:0", for GNU binutils, or ","
735 * for llvm-addr2line, so that we can detect when it has finished giving
736 * us anything useful.
738 len
= snprintf(buf
, sizeof(buf
), "%016"PRIx64
"\n,\n", addr
);
739 written
= len
> 0 ? write(a2l
->in
, buf
, len
) : -1;
740 if (written
!= len
) {
741 if (!symbol_conf
.disable_add2line_warn
)
742 pr_warning("%s %s: could not send request\n", __func__
, dso_name
);
745 io__init(&io
, a2l
->out
, buf
, sizeof(buf
));
746 io
.timeout_ms
= addr2line_timeout_ms
;
747 switch (read_addr2line_record(&io
, a2l_style
, dso_name
, addr
, /*first=*/true,
748 &record_function
, &record_filename
, &record_line_nr
)) {
750 if (!symbol_conf
.disable_add2line_warn
)
751 pr_warning("%s %s: could not read first record\n", __func__
, dso_name
);
755 * The first record was invalid, so return failure, but first
756 * read another record, since we sent a sentinel ',' for the
757 * sake of detected the last inlined function. Treat this as the
758 * first of a record as the ',' generates a new start with GNU
759 * binutils, also force a non-zero address as we're no longer
760 * reading that record.
762 switch (read_addr2line_record(&io
, a2l_style
, dso_name
,
763 /*addr=*/1, /*first=*/true,
766 if (!symbol_conf
.disable_add2line_warn
)
767 pr_warning("%s %s: could not read sentinel record\n",
771 /* The sentinel as expected. */
774 if (!symbol_conf
.disable_add2line_warn
)
775 pr_warning("%s %s: unexpected record instead of sentinel",
781 /* First record as expected. */
786 *file
= strdup(record_filename
);
790 *line_nr
= record_line_nr
;
792 if (unwind_inlines
) {
793 if (node
&& inline_list__append_record(dso
, node
, sym
,
803 * We have to read the records even if we don't care about the inline
804 * info. This isn't the first record and force the address to non-zero
805 * as we're reading records beyond the first.
807 while ((record_status
= read_addr2line_record(&io
,
814 &record_line_nr
)) == 1) {
815 if (unwind_inlines
&& node
&& inline_count
++ < MAX_INLINE_NEST
) {
816 if (inline_list__append_record(dso
, node
, sym
,
823 ret
= 1; /* found at least one inline frame */
828 free(record_function
);
829 free(record_filename
);
831 dso__set_a2l(dso
, NULL
);
832 addr2line_subprocess_cleanup(a2l
);
837 void dso__free_a2l(struct dso
*dso
)
839 struct child_process
*a2l
= dso__a2l(dso
);
844 addr2line_subprocess_cleanup(a2l
);
846 dso__set_a2l(dso
, NULL
);
849 #endif /* HAVE_LIBBFD_SUPPORT */
851 static struct inline_node
*addr2inlines(const char *dso_name
, u64 addr
,
852 struct dso
*dso
, struct symbol
*sym
)
854 struct inline_node
*node
;
856 node
= zalloc(sizeof(*node
));
858 perror("not enough memory for the inline node");
862 INIT_LIST_HEAD(&node
->val
);
865 addr2line(dso_name
, addr
, NULL
, NULL
, dso
, true, node
, sym
);
870 * Number of addr2line failures (without success) before disabling it for that
873 #define A2L_FAIL_LIMIT 123
875 char *__get_srcline(struct dso
*dso
, u64 addr
, struct symbol
*sym
,
876 bool show_sym
, bool show_addr
, bool unwind_inlines
,
882 const char *dso_name
;
884 if (!dso__has_srcline(dso
))
887 dso_name
= srcline_dso_name(dso
);
888 if (dso_name
== NULL
)
891 if (!addr2line(dso_name
, addr
, &file
, &line
, dso
,
892 unwind_inlines
, NULL
, sym
))
895 srcline
= srcline_from_fileline(file
, line
);
901 dso__set_a2l_fails(dso
, 0);
906 dso__set_a2l_fails(dso
, dso__a2l_fails(dso
) + 1);
907 if (dso__a2l_fails(dso
) > A2L_FAIL_LIMIT
) {
908 dso__set_has_srcline(dso
, false);
913 return (show_sym
&& sym
) ?
914 strndup(sym
->name
, sym
->namelen
) : SRCLINE_UNKNOWN
;
917 if (asprintf(&srcline
, "%s+%" PRIu64
, show_sym
? sym
->name
: "",
918 ip
- sym
->start
) < 0)
919 return SRCLINE_UNKNOWN
;
920 } else if (asprintf(&srcline
, "%s[%" PRIx64
"]", dso__short_name(dso
), addr
) < 0)
921 return SRCLINE_UNKNOWN
;
925 /* Returns filename and fills in line number in line */
926 char *get_srcline_split(struct dso
*dso
, u64 addr
, unsigned *line
)
929 const char *dso_name
;
931 if (!dso__has_srcline(dso
))
934 dso_name
= srcline_dso_name(dso
);
935 if (dso_name
== NULL
)
938 if (!addr2line(dso_name
, addr
, &file
, line
, dso
, true, NULL
, NULL
))
941 dso__set_a2l_fails(dso
, 0);
945 dso__set_a2l_fails(dso
, dso__a2l_fails(dso
) + 1);
946 if (dso__a2l_fails(dso
) > A2L_FAIL_LIMIT
) {
947 dso__set_has_srcline(dso
, false);
954 void zfree_srcline(char **srcline
)
956 if (*srcline
== NULL
)
959 if (*srcline
!= SRCLINE_UNKNOWN
)
965 char *get_srcline(struct dso
*dso
, u64 addr
, struct symbol
*sym
,
966 bool show_sym
, bool show_addr
, u64 ip
)
968 return __get_srcline(dso
, addr
, sym
, show_sym
, show_addr
, false, ip
);
971 struct srcline_node
{
974 struct rb_node rb_node
;
977 void srcline__tree_insert(struct rb_root_cached
*tree
, u64 addr
, char *srcline
)
979 struct rb_node
**p
= &tree
->rb_root
.rb_node
;
980 struct rb_node
*parent
= NULL
;
981 struct srcline_node
*i
, *node
;
982 bool leftmost
= true;
984 node
= zalloc(sizeof(struct srcline_node
));
986 perror("not enough memory for the srcline node");
991 node
->srcline
= srcline
;
995 i
= rb_entry(parent
, struct srcline_node
, rb_node
);
1003 rb_link_node(&node
->rb_node
, parent
, p
);
1004 rb_insert_color_cached(&node
->rb_node
, tree
, leftmost
);
1007 char *srcline__tree_find(struct rb_root_cached
*tree
, u64 addr
)
1009 struct rb_node
*n
= tree
->rb_root
.rb_node
;
1012 struct srcline_node
*i
= rb_entry(n
, struct srcline_node
,
1017 else if (addr
> i
->addr
)
1026 void srcline__tree_delete(struct rb_root_cached
*tree
)
1028 struct srcline_node
*pos
;
1029 struct rb_node
*next
= rb_first_cached(tree
);
1032 pos
= rb_entry(next
, struct srcline_node
, rb_node
);
1033 next
= rb_next(&pos
->rb_node
);
1034 rb_erase_cached(&pos
->rb_node
, tree
);
1035 zfree_srcline(&pos
->srcline
);
1040 struct inline_node
*dso__parse_addr_inlines(struct dso
*dso
, u64 addr
,
1043 const char *dso_name
;
1045 dso_name
= srcline_dso_name(dso
);
1046 if (dso_name
== NULL
)
1049 return addr2inlines(dso_name
, addr
, dso
, sym
);
1052 void inline_node__delete(struct inline_node
*node
)
1054 struct inline_list
*ilist
, *tmp
;
1056 list_for_each_entry_safe(ilist
, tmp
, &node
->val
, list
) {
1057 list_del_init(&ilist
->list
);
1058 zfree_srcline(&ilist
->srcline
);
1059 /* only the inlined symbols are owned by the list */
1060 if (ilist
->symbol
&& ilist
->symbol
->inlined
)
1061 symbol__delete(ilist
->symbol
);
1068 void inlines__tree_insert(struct rb_root_cached
*tree
,
1069 struct inline_node
*inlines
)
1071 struct rb_node
**p
= &tree
->rb_root
.rb_node
;
1072 struct rb_node
*parent
= NULL
;
1073 const u64 addr
= inlines
->addr
;
1074 struct inline_node
*i
;
1075 bool leftmost
= true;
1077 while (*p
!= NULL
) {
1079 i
= rb_entry(parent
, struct inline_node
, rb_node
);
1083 p
= &(*p
)->rb_right
;
1087 rb_link_node(&inlines
->rb_node
, parent
, p
);
1088 rb_insert_color_cached(&inlines
->rb_node
, tree
, leftmost
);
1091 struct inline_node
*inlines__tree_find(struct rb_root_cached
*tree
, u64 addr
)
1093 struct rb_node
*n
= tree
->rb_root
.rb_node
;
1096 struct inline_node
*i
= rb_entry(n
, struct inline_node
,
1101 else if (addr
> i
->addr
)
1110 void inlines__tree_delete(struct rb_root_cached
*tree
)
1112 struct inline_node
*pos
;
1113 struct rb_node
*next
= rb_first_cached(tree
);
1116 pos
= rb_entry(next
, struct inline_node
, rb_node
);
1117 next
= rb_next(&pos
->rb_node
);
1118 rb_erase_cached(&pos
->rb_node
, tree
);
1119 inline_node__delete(pos
);