Page 1 of 1
zmtrigger.pl failure in versions over 1.30.4
Posted: Sat Sep 15, 2018 6:09 pm
by rockedge
I have been debugging zmtrigger.pl and why it seems broken. I am using zmalarm.pl to help the debug process which also has stopped working in version ZM 1.31+. It appears that zmtrigger.pl uses functions in /usr/share/perl5/zoneminder/Memory.pm to determine information on monitors.
on line 326 in Memory.pm there is a call to a subroutine that does not seem to exist. The error from zmtrigger.pl seems to involve zmMemGet.
Code: Select all
09/15/2018 11:32:00.800385 zmtrigger[16217].WAR [main:352] [Can't find monitor '1' for message '1|off|||']
The sub zmMemRead has the call to zmMemGet that I can not find at all.
Code: Select all
my $data = zmMemGet( $monitor, $offset, $size );
Does anyone know where this function is supposed to be?
the list of functions:
Code: Select all
zmMemVerify
zmMemInvalidate
zmMemRead
zmMemWrite
zmMemTidy
zmGetMonitorState
zmGetAlarmLocation
zmIsAlarmed
zmInAlarm
zmHasAlarmed
zmGetStartupTime
zmGetLastEvent
zmGetLastWriteTime
zmGetLastReadTime
zmMonitorEnable
zmMonitorDisable
zmMonitorSuspend
zmMonitorResume
zmTriggerEventOn
zmTriggerEventOff
zmTriggerEventCancel
zmTriggerShowtext
Re: zmtrigger.pl failure in versions over 1.30.4
Posted: Mon Sep 17, 2018 1:13 pm
by knight-of-ni
One simple way to find a particular function call within any project is to grep the source code for it:
Code: Select all
$ grep -r zmMemGet ./
./scripts/ZoneMinder/lib/ZoneMinder/Memory.pm.in: my $data = zmMemGet( $monitor, $offset, $size );
./scripts/ZoneMinder/lib/ZoneMinder/Memory/Mapped.pm: zmMemGet
./scripts/ZoneMinder/lib/ZoneMinder/Memory/Mapped.pm:sub zmMemGet {
./scripts/ZoneMinder/lib/ZoneMinder/Memory/Shared.pm: zmMemGet
./scripts/ZoneMinder/lib/ZoneMinder/Memory/Shared.pm:sub zmMemGet
As you can see there are two zmMemGet subroutines. If we can assume you are using mapped memory (the defailt) then that narrows down which subroutine you should be looking at.
Not all monitor types are compatible with zmtrigger so, for example, if the monitor is in monitor mode then the error you posted is expected.
Until you mentioned zm-alarm.pl, I did not know it existed. It appears to live under the /utils folder and is not part of the normal ZoneMinder distribution. It has a last modified time stamp of 5 years ago, so I would not be surprised if it requires an update.
Re: zmtrigger.pl failure in versions over 1.30.4
Posted: Mon Sep 17, 2018 4:46 pm
by rockedge
Yes I see them now ...I found them with grep as well. I am looking at the code run today.
zm-alarm.pl has been a real gold mine. I based all kinds of PERL scripts for zoneminder external triggers and others on it. and using the PERL pm for zoneminder as sort of an API. Mostly for using some old X10 equipment to do motion detection at night and fire up some lights and ZM events, which works quite well actually
it works all the way through 1.30.4 and for awhile on 1.31.1
I am hoping there is an easy fix....maybe PERL has some changes? Anyway I am looking into getting zmtrigger.pl to run on 1.32
Re: zmtrigger.pl failure in versions over 1.30.4
Posted: Wed Sep 19, 2018 1:49 pm
by rockedge
I found that the error causing zmtrigger.pl to fail is the same in zm-alarm.pl and that it centers around Mmap. Both programs error in the same subroutine in Mapped.pm on the same line of code.
the calls start in zmtrigger.pl to the PERL modules which begins with checking "shared" or "mapped" and flows through Zoneminder.pm and Memory.pm to the subroutine zmMemGet in Mapped.pm. The sub zmMemGet at line 156 fails because the SCALAR variable $mmap
has no value and is empty.
Code: Select all
my $mmap = $monitor->{MMap};
if ( !$mmap || !$$mmap )
{
Error( sprintf( "Can't read from mapped memory for monitor '%d', gone away?"
, $monitor->{Id}
)
);
return( undef );
}
my $data = substr( $$mmap, $offset, $size );
return( $data );
}
in subroutine zmMemAttach in Mapped.pm line 114 may be failing which in turn causes line 123 which is
$monitor->{MMap} = \$mmap; to be empty and no value
Code: Select all
my $mmap = undef;
my $mmap_addr = mmap( $mmap, $size, PROT_READ|PROT_WRITE, MAP_SHARED, $MMAP );
if ( !$mmap_addr || !$mmap )
{
Error( sprintf( "Can't mmap to file '%s': $!\n", $mmap_file ) );
close( $MMAP );
return( undef );
}
$monitor->{MMapHandle} = $MMAP;
$monitor->{MMapAddr} = $mmap_addr;
$monitor->{MMap} = \$mmap;
}
return( !undef );
}
so it appears that something in the functions of Sys:: Mmap has changed.
I compared the running code using PERL -d and by following into the subroutines with "s" watched how zmtrigger.pl runs in ZM 1.30.4 and ZM 1.32 side by side to observe this behavior. by using the "p" in the debugger to print the variable values a SCALAR value is present when "p $monitor->{Mmap} right after the line 176 in Mapped.pm is executed in version 1.30.4 and is completely empty in ZM 1.32
Re: zmtrigger.pl failure in versions over 1.30.4
Posted: Wed Sep 19, 2018 4:01 pm
by iconnor
Just a random thought... if a person closes all the file handles (STDIN,STDOUT, etc) then when you open a new file, you COULD get 0 for the file handle. Perhaps $mmap can be 0. Perhaps the if ( !$mmap_addr || ! $mmap ) should just be if ( !$mmap_addr)
Re: zmtrigger.pl failure in versions over 1.30.4
Posted: Wed Sep 19, 2018 5:11 pm
by knight-of-ni
zm-alarm.pl is definitely broken. It simply needed to be updated to the latest way of accessing mapped memory.
The following commit fixes zm-alarm on my test system:
https://github.com/ZoneMinder/zoneminde ... d848c45aa7
zmtrigger continues to work fine for me, however. See the comments I left for you in our slack channel.