zmtrigger.pl failure in versions over 1.30.4

Forum for questions and support relating to the 1.31.x releases only.
Locked
rockedge
Posts: 1173
Joined: Fri Apr 04, 2014 1:46 pm
Location: Connecticut,USA

zmtrigger.pl failure in versions over 1.30.4

Post 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
User avatar
knight-of-ni
Posts: 2404
Joined: Thu Oct 18, 2007 1:55 pm
Location: Shiloh, IL

Re: zmtrigger.pl failure in versions over 1.30.4

Post 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.
Visit my blog for ZoneMinder related projects using the Raspberry Pi, Orange Pi, Odroid, and the ESP8266
All of these can be found at https://zoneminder.blogspot.com/
rockedge
Posts: 1173
Joined: Fri Apr 04, 2014 1:46 pm
Location: Connecticut,USA

Re: zmtrigger.pl failure in versions over 1.30.4

Post 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
rockedge
Posts: 1173
Joined: Fri Apr 04, 2014 1:46 pm
Location: Connecticut,USA

Re: zmtrigger.pl failure in versions over 1.30.4

Post 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
User avatar
iconnor
Posts: 2896
Joined: Fri Oct 29, 2010 1:43 am
Location: Toronto
Contact:

Re: zmtrigger.pl failure in versions over 1.30.4

Post 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)
User avatar
knight-of-ni
Posts: 2404
Joined: Thu Oct 18, 2007 1:55 pm
Location: Shiloh, IL

Re: zmtrigger.pl failure in versions over 1.30.4

Post 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.
Visit my blog for ZoneMinder related projects using the Raspberry Pi, Orange Pi, Odroid, and the ESP8266
All of these can be found at https://zoneminder.blogspot.com/
Locked