Currently, libunwind allocates several PATH_MAX entries on stack, while
trying to find a binary via /proc/.../maps.
However stack space may be at premium (especially when sigaltstack is used),
and PATH_MAX on Linux is 4096, while SIGSTKSZ is only 8192 on x86.
Attached patch eliminates multiple PATH_MAX stack allocations, and simplifies
code in maps_next, at the cost of being unable to do anything if we can't
mmap one page. It appears to me that under such low-memory conditions,
libunwind will fail shortly elsewhere anyway.
This patch also disables more of debug_frame-handling code when
CONFIG_DEBUG_FRAME is undefined.
Tested on Linux/x86_64 with and without CONFIG_DEBUG_FRAME, no regressions.
The behavior on wait vs abort unwind depends on the locking primitive
chosen by the user. This makes the API consistent and independent of
the locking primitive.
Greetings,
We use libunwind just for stack traces (I suspect many others do as well).
The use pattern is:
GetStackTrace(void** result, int max_depth)
{
...
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
while (n < max_depth) {
if (unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip) < 0) {
break;
}
result[n++] = ip;
if (unw_step(&cursor) <= 0) {
break;
}
}
Given this usage, it is quite convenient for us to block signals (or
prevent signal handlers from re-entering libunwind by other means) at the
"top level", which makes most of the sigprocmask calls performed by
libunwind itself unneccessary.
The second patch in this series adds a configure option which removes most
of the sigprocmask calls.
Attached patch is a preliminary for it -- consolidating all of the
"sigprocmask; mutex_lock;" sequences into lock_acquire and "mutex_unlock;
sigprocmask;" sequences into lock_release.
Thanks,
--
Paul Pluzhnikov
commit 402d15b123d54a7669db7cf17a76dd315094e472
Author: Paul Pluzhnikov <ppluzhnikov@google.com>
Date: Mon Sep 21 10:18:28 2009 -0700
Replace "sigprocmask + mutext_lock" with a single lock_acquire.
Likewise, replace "mutext_unlock + sigprocmask" with lock_release.
Yes, it casts to signed, but then converts right back to
unsigned via the return type. Fixed thus.
Signed-off-by: Richard Henderson <rth@redhat.com>
Signed-off-by: Arun Sharma <arun.sharma@google.com>
Now that dwarf_find_save_locs() not just finds the save-locations but
also updates the cursor-state, document this fact (the function really
is misnamed now).
2004/11/17 02:43:39-08:00 mostang.com!davidm
(struct callback_data): New structure.
(linear_search): New function.
(callback): Convert to getting auxiliary info passed via a pointer to
a callback_data structure, rather than an unw_dyn_info_t
structure.
Keep track of the maximum load address in max_load_addr.
If an object doesn't have a binary search-table, fall back
on a linear search.
(dwarf_find_proc_info): Fill in callback-data structure before calling
dl_iterate_phdr(). Upon returning, check whether
cb_data.single_fde is set and, if so, return directly, without
searching the DWARF unwind-table.
(dwarf_search_unwind_table): Adjust for renaming of
dwarf_parse_fde() to dwarf_extract_proc_info_from_fde().
If IP doesn't fall into the IP-range of the FDE-entry found
by the search, return UNW_ENOINFO.
(Logical change 1.290)
(parse_cie): Adjust for moving DWARF2 extra-info from
unw_dyn_dwarf_fde_info_t to dwarf_cie_info.
Add support for `S' augmentation ("special frames").
(dwarf_extract_proc_info_from_fde): Rename frm dwarf_parse_fde().
Convert to returning data via dwarf_cie_info rather than
unw_dyn-dwarf_fde_info_t. Allow 0-length FDE since those
can be used to indicate the end of the FDE-table. Return
the end of the FDE via *ADDRP. Ignore CIEs (we may pick them
up during linear searches through the FDE-table).
Fill in the unwind-info only if really needed. When needed,
return the info via a dynamically allocated dwarf_cie_info
structure. Add support for `S' augmentation (ABI/tag pairs).
(Logical change 1.290)
unwind-info, since DWARF expects us to do so (unlikey for ia64,
where we are guaranteed that the (return) IP points to the
correct unwind-info).
2004/11/17 02:43:39-08:00 mostang.com!davidm
(run_cfi_program): Switch over to using dwarf_cie_info instead of
unw_dyn_dwarf_fde_info_t.
(fetch_proc_info): Clear c->pi before filling it in.
(put_unwind_info): If we got non-dynamic unwind-info, free it
via a call to mempool_free().
(parse_fde): Switch over to using dwarf_cie_info instead of
unw_dyn_dwarf_fde_info_t.
(apply_reg_state): Drop accessees to c->cfa_is_sp.
2004/10/25 17:38:51+02:00 homeip.net!davidm
Fix typo: DW_CFA_CFA_expression -> DW_CFA_expression.
2004/10/21 11:15:44+02:00 homeip.net!davidm
Auto merged
2004/10/21 11:15:12+02:00 homeip.net!davidm
(run_cfi_program): Add missing newline in Debug statement.
(apply_reg_state): It was wrong to do a dwarf_get() on the CFA-location
returned by eval_location_expr(). Instead, we must make sure
we're dealing with a memory-location and, if so, just extract
the memory address as the CFA.
Also, update c->cfa only _after_ the other frame-state has
been updated. This seems to be necessary for correct parsing
of the sigtramp unwind info. Not sure yet this is 100% correct,
but it gets us through Gtest-resume-sig.
2004/10/19 23:24:56-07:00 mostang.com!davidm
(run_cfi_program): Fix typos in Debug statements.
(Logical change 1.290)
2004/10/19 23:15:02-07:00 mostang.com!davidm
(update_frame_state): Take additional argument "prev_cfa".
When we detect a NULL-frame, debug-print the IP and the CFA
so we know where things went wrong.
(dwarf_step): Get "prev_cfa" before we call dwarf_find_save_locs(),
since update_frame_state() doesn't actually update
the CFA.
(Logical change 1.290)
(pick): Likewise.
(dwarf_eval_expr): Fix "while" conditional so we see all operators.
Fix DW_OP_litN typo: "opcode = DW_OP_lit0" to
"opcode - DW_OP_lit0".
Add lots of Debug() statements so we can see what's going
on. Debug level 15 will show just entry/return values.
Debug level 16 shows all operators.
(Logical change 1.290)
printing them. Avoids compiler-warning for 64-bit targets.
(apply_reg_state): Handle the special case where the stack-pointer
plays the role of the CFA and the stack-pointer hasn't
been saved. This is based on a patch by Max Asbock.
(Logical change 1.253)
Drop DWARF-parsing debug prints from level 16 to 15.
(struct table_entry): Change member types from unw_word_t to int32_t. The members
need to be of a signed type and forcing them to 32 bits makes the type
work for both 32-bit and 64-bit executables (up to 4GB of text-size).
(callback): Only allow search tables which have 32-bit members.
Fix initialization of di->u.rti.table_len to express table-length as a count
of unw_word_t, as it's defined to be (we get lucky here: even with 32-bit
members, each table-entry contains two members so we're guaranteed that the
table has a size that is an integer-multiple of unw_word_t even on 64-bit
platforms).
(lookup): Change type of "rel_ip" from unw_word_t to int32_t. Simplify the
code a bit.
(remote_read): Delete.
(remote_lookup): Use dwarf_reads32() instead of remote_read() to read out table
members. Simplify code a bit.
(Logical change 1.248)