Hang with ExifTool in NSOperation (Mac Cocoa)

Started by DesertNomad, October 04, 2018, 12:27:28 PM

Previous topic - Next topic

DesertNomad

Yes, I was trying to say that I can't access the ExifTool object from multiple threads. I'll try 1.06 and disable the watchdog.

Phil Harvey

#16
I've been playing around with this myself using a basic Cocoa project with the attached main.mm

I don't get any crashes, but always it seems that 1 operation never completes.

- Phil

Edit:  Debugging this, I don't think that exiftool is actually running at all, so I have done something wrong.  The path to ExifTool was wrong, but if I set it correctly it does the same thing.
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Phil Harvey

Some odd is happening in Cocoa.  If I compile with gcc and run this code as a C++ main

int main(int argc, char **argv)
{
    printf("Created!\n");
    ExifTool::sNoWatchdog = 1;
    ExifTool* tool = new ExifTool("/usr/bin/perl","/Users/phil/bin/exiftool");
    printf("Is Running before: %d\n",tool->IsRunning());
    TagInfo *info = tool->ImageInfo("/Users/phil/source/exiftool_cvs/t/images/ExifTool.jpg");
    printf(" %s\n", info ? "good" : "BAD!");
    if (not info) {
        printf(" LastComplete = %d\n",tool->LastComplete());
        char *err = tool->GetError();
        if (err) printf(" ERROR %s\n",err);
    }
    printf("Is Running after: %d\n",tool->IsRunning());

    delete tool;
}


it gives this output:

Created!
Is Running before: 1
good
Is Running after: 1


but if I compile in XCode as a .mm main function (no NSOperations at all), it gives this:

Created!
Is Running before: 1
BAD!
LastComplete = -1
Is Running after: 0


That's about as far as I can go now because I can't even get this working in Cocoa without the NSOperation complication.  And I've run out of time today to look at this.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

DesertNomad

#18
It might not like how you are creating the path in the NSOperation. I was using:

NSString* toolPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"/exiftool/exiftool"];
ExifTool* tool = new ExifTool([toolPath cStringUsingEncoding:NSUTF8StringEncoding]);

in dealloc, you should be calling [super dealloc];

Maybe this would be easier from an NSTask running the command line tool. Is there a way to get the same data as exists in a TagInfo struct in a clean (json for example) way from the command line?


DesertNomad

#19
I can't seem to get group 0, 1 and 2 at the same time using the terminal in the same way that I can using the C++ TagInfo struct. When I use the NSTask based command line, I don't get a hang, but the data returned has less detail than I can get with the C++ method.

With a TagInfo struct I can get:

Type(g0) = XMP;
Location(g1) = "XMP-dc";
Category(g2) = Image;
Description = Subject;
Name = Subject;
NumberValue = "KeywordA, KeywordB";
StringValue = "KeywordA, KeywordB";

With the terminal I can only see one of the group values.

UPDATE: It is easy to get the hang when using the C++ method while running from Xcode (and thus with a debugger active). In the release build, I have not yet seen the hang. Could this be some interaction with the debugger? When the hang happens, it is my app that has the spinning beech ball, not Xcode. Such a mystery as during the hang I can't break into the debugger and see anything useful.

Phil Harvey

Ah.  It could be that the debugger is trapping signals that are necessary for the ExifTool processes (like the SIGINT that is used to kill the watchdog process).

From the command line, use -php -l -G:0:1:2:4 -D -sep ", " to get the output that the ExifTool object uses.  This will give you all three groups plus the copy number.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

DesertNomad

That works well enough to parse... just looks likes I have to break out the Groups by the colon separator.

Is there a way to get a json output with those already split?

The debug version hangs even if I launch it without the debugger running, but the release build seems to work fine (so far). I wonder if there are hooks in the debug build that interfere with it?

Phil Harvey

Quote from: DesertNomad on October 06, 2018, 02:58:11 PM
Is there a way to get a json output with those already split?

No.  You've got to split them yourself.

QuoteThe debug version hangs even if I launch it without the debugger running, but the release build seems to work fine (so far). I wonder if there are hooks in the debug build that interfere with it?

Sounds like there is, but maybe someone on a Cocoa forum knows about this.  It would be good to know so I could add some tips to the documentation for Cocoa programmers.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

DesertNomad

I'll let you know if I find out anything more about the hang.

As to splitting the groups, I assume that a colon can't appear in the group names so is safe to use to split things.

Phil Harvey

Yes.  Group and tag names may contain only A-Z, a-z, 0-9, - and _.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).