summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2008-04-13 17:50:45 -0400
committerFrank Ch. Eigler <fche@elastic.org>2008-04-13 17:50:45 -0400
commitf7e07777e033e580351dc6886ab7dbdddd9839fe (patch)
tree07c4878e3eaf77801d5104c2f6c498cfff9e3bbd /runtime
parenta9f3ab125303a2e89dd3c17b39f26e1d2c428fa5 (diff)
downloadsystemtap-steved-f7e07777e033e580351dc6886ab7dbdddd9839fe.tar.gz
systemtap-steved-f7e07777e033e580351dc6886ab7dbdddd9839fe.tar.xz
systemtap-steved-f7e07777e033e580351dc6886ab7dbdddd9839fe.zip
runtime backtrace: stop infinite loops by checking for full print buffer
2008-04-13 Frank Ch. Eigler <fche@elastic.org> * print.c (_stp_pbuf_full): New function to note full print buffer. * stack-{i386,x86_64}.c: Use it in all stack-searching loops, to impose another limit against unbounded iteration.
Diffstat (limited to 'runtime')
-rw-r--r--runtime/ChangeLog6
-rw-r--r--runtime/print.c10
-rw-r--r--runtime/stack-i386.c9
-rw-r--r--runtime/stack-x86_64.c3
4 files changed, 24 insertions, 4 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index 067c5820..09a3e35d 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,9 @@
+2008-04-13 Frank Ch. Eigler <fche@elastic.org>
+
+ * print.c (_stp_pbuf_full): New function to note full print buffer.
+ * stack-{i386,x86_64}.c: Use it in all stack-searching loops, to
+ impose another limit against unbounded iteration.
+
2008-03-31 Martin Hunt <hunt@redhat.com>
* runtime.h (STP_USE_DWARF_UNWINDER): Define.
diff --git a/runtime/print.c b/runtime/print.c
index 0442ba09..4f99be7b 100644
--- a/runtime/print.c
+++ b/runtime/print.c
@@ -243,6 +243,16 @@ void _stp_print_char (const char c)
pb->len ++;
}
+/** Check whether the print buffer is full.
+ * @return non-zero if full
+ */
+
+static int _stp_pbuf_full (void)
+{
+ _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id());
+ return (pb->len >= STP_BUFFER_SIZE);
+}
+
/* This function is used when printing maps or stats. */
/* Probably belongs elsewhere, but is here for now. */
diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c
index 20c8eda5..78f89b0d 100644
--- a/runtime/stack-i386.c
+++ b/runtime/stack-i386.c
@@ -17,7 +17,8 @@ static int _stp_valid_stack_ptr(unsigned long context, unsigned long p)
static void _stp_stack_print_fallback(unsigned long context, unsigned long stack, int verbose)
{
unsigned long addr;
- while (_stp_valid_stack_ptr(context, stack)) {
+ while (_stp_valid_stack_ptr(context, stack) &&
+ !_stp_pbuf_full()) {
if (unlikely(_stp_read_address(addr, (unsigned long *)stack, KERNEL_DS))) {
/* cannot access stack. give up. */
return;
@@ -42,7 +43,8 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels)
unsigned long ebp = regs->ebp;
#endif /* STAPCONF_X86_UNIREGS */
- while (_stp_valid_stack_ptr(context, (unsigned long)ebp)) {
+ while (_stp_valid_stack_ptr(context, (unsigned long)ebp) &&
+ !_stp_pbuf_full()) {
if (unlikely(_stp_read_address(addr, (unsigned long *)(ebp + 4), KERNEL_DS))) {
/* cannot access stack. give up. */
return;
@@ -59,7 +61,8 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels)
struct unwind_frame_info info;
arch_unw_init_frame_info(&info, regs);
- while (!arch_unw_user_mode(&info)) {
+ while (!arch_unw_user_mode(&info) &&
+ !_stp_pbuf_full ()) {
int ret = unwind(&info);
dbug_unwind(1, "ret=%d PC=%lx SP=%lx\n", ret, UNW_PC(&info), UNW_SP(&info));
if (ret == 0) {
diff --git a/runtime/stack-x86_64.c b/runtime/stack-x86_64.c
index ae8e446d..9915c594 100644
--- a/runtime/stack-x86_64.c
+++ b/runtime/stack-x86_64.c
@@ -12,7 +12,8 @@
static void _stp_stack_print_fallback(unsigned long stack, int verbose)
{
unsigned long addr;
- while (stack & (THREAD_SIZE - 1)) {
+ while (stack & (THREAD_SIZE - 1) &&
+ !_stp_pbuf_full()) {
if (unlikely(_stp_read_address(addr, (unsigned long *)stack, KERNEL_DS))) {
/* cannot access stack. give up. */
return;