diff --git a/fhem/FHEM/98_fhemdebug.pm b/fhem/FHEM/98_fhemdebug.pm index f1df7ebd7..f8ab9e2ff 100644 --- a/fhem/FHEM/98_fhemdebug.pm +++ b/fhem/FHEM/98_fhemdebug.pm @@ -40,8 +40,17 @@ fhemdebug_Fn($$) } elsif($param =~ m/^memusage/) { return fhemdebug_memusage($param); + } elsif($param =~ m/^timerList/) { + return fhemdebug_timerList($param); + + } elsif($param =~ m/^addTimerStacktrace/) { + $param =~ s/addTimerStacktrace\s*//; + $addTimerStacktrace = $param; + return; + } else { - return "Usage: fhemdebug {enable|disable|status|memusage}"; + return "Usage: fhemdebug {enable | disable | status | memusage | ". + "timerList | addTimerStacktrace {0|1} }"; } } @@ -162,6 +171,21 @@ fhemdebug_memusage($) return join("\n", @ret); } +sub +fhemdebug_timerList($) +{ + my ($param) = @_; + my @res; + + for my $h (@intAtA) { + my $tt = $h->{TRIGGERTIME}; + push(@res, sprintf("%s.%05d %s%s", + FmtDateTime($tt), int(($tt-int($tt))*100000), $h->{FN}, + $h->{STACKTRACE} ? $h->{STACKTRACE} : "")); + } + return join("\n", @res); +} + 1; =pod @@ -173,8 +197,9 @@ fhemdebug_memusage($)

fhemdebug

diff --git a/fhem/fhem.pl b/fhem/fhem.pl index e7ff6cd22..52cfdd561 100755 --- a/fhem/fhem.pl +++ b/fhem/fhem.pl @@ -259,6 +259,7 @@ use vars qw(@structChangeHist); # Contains the last 10 structural changes use vars qw($haveInet6); # Using INET6 use vars qw(%prioQueues); # use vars qw($fhemForked); # 1 in a fhemFork()'ed process, else undef +use vars qw($addTimerStacktrace);# set to 1 by fhemdebug $selectTimestamp = gettimeofday(); $cvsid = '$Id$'; @@ -351,10 +352,18 @@ $modules{Global}{AttrList} = join(" ", @globalAttrList); $modules{Global}{AttrFn} = "GlobalAttr"; use vars qw($readingFnAttributes); -$readingFnAttributes = "event-on-change-reading event-on-update-reading ". - "event-aggregator event-min-interval ". - "stateFormat:textField-long timestamp-on-change-reading ". - "oldreadings"; +no warnings 'qw'; +my @attrList = qw( + event-aggregator + event-min-interval + event-on-change-reading + event-on-update-reading + oldreadings + stateFormat:textField-long + timestamp-on-change-reading +); +$readingFnAttributes = join(" ", @attrList); + my %ra = ( "suppressReading" => { s=>"\n" }, "event-aggregator" => { s=>",", c=>".attraggr" }, @@ -3151,6 +3160,7 @@ InternalTimer($$$;$) $nextat = $tim if(!$nextat || $nextat > $tim); my %h = (TRIGGERTIME=>$tim, FN=>$fn, ARG=>$arg, atNr=>++$intAtCnt); + $h{STACKTRACE} = stacktraceAsString(1) if($addTimerStacktrace); $intAt{$h{atNr}} = \%h; if(!@intAtA) { @@ -3206,6 +3216,20 @@ stacktrace() } } +sub +stacktraceAsString($) +{ + my ($offset) = @_; + $offset = 1 if (!$offset); + my ($max_depth,$ret) = (50,""); + + while( (my @call_details = (caller($offset++))) && ($offset<$max_depth) ) { + $call_details[3] =~ s/main:://; + $ret .= sprintf(" %s:%s", $call_details[3], $call_details[2]); + } + return $ret; +} + my $inWarnSub; sub