2

I have an application that reads in text by emulating CMD-C copy commands and reading the pasteboard - unfortunately this the only way to achieve what I need. Occasionally, as this is under development, once in a while I do something wrong (I don't think it's related to the copy command) and the app crashes. Once in a while, this has a knock on effect on the system-wide pasteboard - any other application that is running will crash if I attempt a copy, cut, or paste.

Is there a robust way to handle this - something I should be doing with the NSPasteboard before exiting? Any information on what might be happening is appreciated.

For completeness, here are the only snippets of code that access the pasteboard:

Reading from the pasteboard:

NSString *pBoardText = [[NSPasteboard generalPasteboard]stringForType:NSStringPboardType];

Initially clearing the pasteboard (I run this only once, at launch):

[[NSPasteboard generalPasteboard] declareTypes: [NSArray arrayWithObject:NSStringPboardType] owner: self];
    [[NSPasteboard generalPasteboard] setString: @"" forType: NSStringPboardType];

PS I forgot to mention that this copy command runs on a loop, in a different thread - could be important. Although I've been careful not to access the pasteboard on the main thread without checking first that the loop is stopped.

Update - a few questions about what I am doing...

  • Can you post a crash report

Working on it right now - unfortunately the crashes are irregular. Let me be clear though - this is an application I am still developing, and sometimes I introduce a bug. When this results in a crash, the system-wide pasteboard gets messed up SOMETIMES. It doesn't look like the pasteboard access in my app is CAUSING the crash though, instead that it exits while the background loop is at a delicate stage of interacting with the PB. Update - Re the crash report - how important is this to you guys? I'm still developing, but can try to run it a few times not in the debugger until something breaks. Unfortunately I fixed all outstanding bugs for now and am not getting any crashes. This strongly suggests to me that the problem is not with the PBoard code itself - I'm more looking for some safeguards, so that if there IS a crash, it doesn't bring down my whole system. All these restarts are getting annoying.

  • Can you elaborate on why you need to emulate Cmd-C to do what you need?

I am scraping text from a chat box on an external application. The chat box is built to prohibit me from using the Accessibility interface or any other means.

  • Why are you clearing the contents of the clipboard on launch?

I examine the pasteboard text for new text. This was is a quick way to make sure that I don't process text copied from some other application.

  • Why are you running the code on a thread at all?

The loop continually posts events to simulate user input, including switching to the chat window, and copying the selected text. If this is done on the main thread, my app UI will just hang. I use the UI to display an overview of what's going on.

  • please show the code that runs on the main thread and checks the loop and accesses the pasteboard

the background thread passes data to the main thread using NSNotifications:

[self performSelectorOnMainThread:@selector(postNote:) withObject:d waitUntilDone:NO];
Ben Packard
  • 26,102
  • 25
  • 102
  • 183
  • Can you show the crash report, and the code where the crash is located? –  May 09 '10 at 08:04
  • It's just a EXC_BAD_ACCESS error - I don't think the app crash is related to the 'stuck' pasteboard. In fact I think the system-wide pasteboard crash is a RESULT of my app exiting in an ugly manner. – Ben Packard May 09 '10 at 08:18
  • The problem is extremely likely to be a threading issue. It sounds like you are doing some pretty funky stuff. Can you elaborate on why you need to emulate Cmd-C to do what you need? Please do post the crash log, we need to see the stack trace to see where the crash is occurring. – Rob Keniger May 09 '10 at 08:51
  • Excuse my ignorance, where do I get the crash log from? I need to copy the contents of a chat box that is updated frequently. The external application I am reading from has a number of measures that prevent using Accessibility or any other means. Just to be clear - I think the crash in my application maybe isn't caused by the pasteboard functionality, but CAUSES the pb (across the whole system) to be messed up - for example if the main thread is crashing my application while the background thread is in a delicate stage of writing/reading the pb. Hope that makes sense. – Ben Packard May 09 '10 at 09:39
  • The crash log will be in the Crash Reporter dialog box that comes up when you run your app outside of the debugger. You can also copy the stack trace from the debugger. – Peter Hosey May 09 '10 at 18:18
  • Why are you clearing the contents of the clipboard on launch? Also, please show the code that runs on the main thread and checks the loop and accesses the pasteboard. – Peter Hosey May 09 '10 at 18:20
  • 1
    Incidentally, why are you running the code on a thread at all? – Peter Hosey May 09 '10 at 18:53
  • The crash report might also be in ~/Library/Logs/CrashReporter – JeremyP May 09 '10 at 22:52
  • Thanks Peter/Jeremy - I've tried to answer in the question, above - please let me know if I've missed something. Getting a crash report asap. – Ben Packard May 09 '10 at 23:59
  • Is this app strictly for your own use, or are you going to be publishing it? If the latter, you really shouldn't be clearing the pasteboard when your app launches. – NSResponder May 10 '10 at 02:22
  • No, totally a tool for my own use - I would never release something that has to do this kind of keyboard posting etc, let alone wiping the user's pasteboard data. – Ben Packard May 10 '10 at 04:34
  • If you're forging events to switch out of your application and into the target, why is not blocking your own UI important? Also, `performSelectorOnMainThread:` is not an NSNotification. – Peter Hosey May 10 '10 at 23:11
  • I still need to view my application, and it also has a 'stop' button. Can you clarify what you are asking for? You asked for the code that runs on the main thread and checks the loop and accesses the pasteboard. No such code exists. The background loop 'spits out' notifications to the main thread. This works fine, though I can show you my NSNotification code if you really think that might be relevant. – Ben Packard May 11 '10 at 03:36
  • At the risk of repeating myself, I'm not trying to identify the bug causing my crash. I'm trying to handle the crash better, without bringing down my whole OS, and to understand why I might be breaking the Pasteboard. Perhaps I haven't made that clear enough, or perhaps you get that already. Thanks for helping. – Ben Packard May 11 '10 at 03:40

1 Answers1

1

Some thoughts:

  • It is highly unlikely that any threading issues within one app will bring down the other applications. As this appears to be your main problem, it seems more likely that the problem is with the data you put on the pasteboard or the description of the data. The apps crash for some reason when they try to use the data on the pasteboard.
  • The code you're using is only for 10.5 or earlier. There were several major changes in the way the pasteboard is used in 10.6. If you're running under 10.6, using the 10.5 methods might might be your problem.
  • One major change in 10.6 is the reliance on UTIs to accurately describe the data on the pasteboard. If the UTI is incorrect or garbled, any app trying to make use of the data based on the assumption it is some other from of data could crash.
  • If you're using 10.6 make sure to use the Pasteboard Programming Guide as your reference and not the older Pasteboard Programming Topics for Cocoa.
Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75
TechZen
  • 64,370
  • 15
  • 118
  • 145