Debugger at odds with reality?

  • I have a funny problem which is proving difficult to fix.

    I have a framework which I've written, and an app which I've written
    that uses it. I can debug to my heart's content in both - make a
    change in the framework, the change is reflected in the app, all is
    well.

    Now I'm trying to help someone out who is also writing an app against
    my framework, and things there are totally weird. I've set up the app
    project identically to my own app (AFAICS) but there are two debugging
    problems which I don't get in my own app. The first is that
    breakpoints in the framework don't cause a break. The second much
    worse problem is that the layout of objects is wrong - it's as if the
    debugger is using some (much) older version of the framework classes
    for its symbol definitions, so when the code tries to set an ivar say,
    some other part of the object gets updated in the debugger. From what
    I can tell the code is right, as things are actually working, but the
    debugger has an out of date view of the code.

    Where does the debugger grab its "picture" of the linked framework from?

    I've copied over all the relevant settings from the first app's
    project to the second app's, but to no avail. The actual build is
    picking up the framework OK, which is copied into its local
    "Frameworks" folder in the bundle, and it runs OK, so it's linking
    against the right framework at runtime - but the debugger obstinately
    refuses to "see" the right framework, and is using a *VERY* old
    version. I've deleted all old versions that I can find but it's still
    getting it from somewhere. Until I can solve this I can't debug the
    app, as the debugger is just showing me garbage.

    Any ideas?

    G.
  • on 4/26/08 7:20 AM, <graham.cox...> purportedly said:

    > I have a funny problem which is proving difficult to fix.
    >
    > I have a framework which I've written, and an app which I've written
    > that uses it. I can debug to my heart's content in both - make a
    > change in the framework, the change is reflected in the app, all is
    > well.
    >
    > Now I'm trying to help someone out who is also writing an app against
    > my framework, and things there are totally weird. I've set up the app
    > project identically to my own app (AFAICS) but there are two debugging
    > problems which I don't get in my own app. The first is that
    > breakpoints in the framework don't cause a break. The second much
    > worse problem is that the layout of objects is wrong - it's as if the
    > debugger is using some (much) older version of the framework classes
    > for its symbol definitions, so when the code tries to set an ivar say,
    > some other part of the object gets updated in the debugger. From what
    > I can tell the code is right, as things are actually working, but the
    > debugger has an out of date view of the code.
    >
    > Where does the debugger grab its "picture" of the linked framework from?

    The first thing I would try is deselecting "lazy symbol loading" under Xcode
    preferences (debugging).

    HTH,

    Keary Suska
    Esoteritech, Inc.
    "Demystifying technology for your home or business"
  • This might be a stupid question, but the person who is building
    against your framework is using a debug version as opposed to a
    release version, correct?

    On Apr 26, 2008, at 6:20 AM, Graham Cox wrote:

    > I have a funny problem which is proving difficult to fix.
    >
    > I have a framework which I've written, and an app which I've written
    > that uses it. I can debug to my heart's content in both - make a
    > change in the framework, the change is reflected in the app, all is
    > well.
    >
    > Now I'm trying to help someone out who is also writing an app
    > against my framework, and things there are totally weird. I've set
    > up the app project identically to my own app (AFAICS) but there are
    > two debugging problems which I don't get in my own app. The first is
    > that breakpoints in the framework don't cause a break. The second
    > much worse problem is that the layout of objects is wrong - it's as
    > if the debugger is using some (much) older version of the framework
    > classes for its symbol definitions, so when the code tries to set an
    > ivar say, some other part of the object gets updated in the
    > debugger. From what I can tell the code is right, as things are
    > actually working, but the debugger has an out of date view of the
    > code.
    >
    > Where does the debugger grab its "picture" of the linked framework
    > from?
    >
    > I've copied over all the relevant settings from the first app's
    > project to the second app's, but to no avail. The actual build is
    > picking up the framework OK, which is copied into its local
    > "Frameworks" folder in the bundle, and it runs OK, so it's linking
    > against the right framework at runtime - but the debugger
    > obstinately refuses to "see" the right framework, and is using a
    > *VERY* old version. I've deleted all old versions that I can find
    > but it's still getting it from somewhere. Until I can solve this I
    > can't debug the app, as the debugger is just showing me garbage.
    >
    > Any ideas?
    >
    >
    > G.
  • In fact not a stupid question.

    There was one place in the framework where a couple of ivars were
    conditionally defined for debugging. Originally the #define for these
    was in the header itself, so you could easily allow them or not, but
    someone decided this would be better off in the precompiled header,
    which of course was different for the two projects, hence one project
    thought the superclass had a size x, where in fact it was x+some.

    That explains the misalignment of the ivars in the debugger, but it
    *doesn't* explain the discrepancy between the actual layout of the
    class in the debugger compared with the latest version of the
    framework - the debugger was still using a layout which was last
    current about five weeks ago. That part I still haven't got to the
    bottom of, though basically throwing every build folder away that I
    could find and forcing a full rebuild ("clean" didn't do it) finally
    kicked into using the current version.

    I'd still like to know more about how all this actually works - I feel
    I'm groping in the dark when things go wrong.

    G.

    On 27 Apr 2008, at 4:14 pm, Colin Cornaby wrote:
    > This might be a stupid question, but the person who is building
    > against your framework is using a debug version as opposed to a
    > release version, correct?
    >
    > On Apr 26, 2008, at 6:20 AM, Graham Cox wrote:
    >
    >> I have a funny problem which is proving difficult to fix.
    >>
    >> I have a framework which I've written, and an app which I've
    >> written that uses it. I can debug to my heart's content in both -
    >> make a change in the framework, the change is reflected in the app,
    >> all is well.
    >>
    >> Now I'm trying to help someone out who is also writing an app
    >> against my framework, and things there are totally weird. I've set
    >> up the app project identically to my own app (AFAICS) but there are
    >> two debugging problems which I don't get in my own app. The first
    >> is that breakpoints in the framework don't cause a break. The
    >> second much worse problem is that the layout of objects is wrong -
    >> it's as if the debugger is using some (much) older version of the
    >> framework classes for its symbol definitions, so when the code
    >> tries to set an ivar say, some other part of the object gets
    >> updated in the debugger. From what I can tell the code is right, as
    >> things are actually working, but the debugger has an out of date
    >> view of the code.
    >>
    >> Where does the debugger grab its "picture" of the linked framework
    >> from?
    >>
    >> I've copied over all the relevant settings from the first app's
    >> project to the second app's, but to no avail. The actual build is
    >> picking up the framework OK, which is copied into its local
    >> "Frameworks" folder in the bundle, and it runs OK, so it's linking
    >> against the right framework at runtime - but the debugger
    >> obstinately refuses to "see" the right framework, and is using a
    >> *VERY* old version. I've deleted all old versions that I can find
    >> but it's still getting it from somewhere. Until I can solve this I
    >> can't debug the app, as the debugger is just showing me garbage.
    >>
    >> Any ideas?
    >>
    >>
    >> G.
    >
  • I've found that trashing the build folder is often a worthwhile step,
    and one other thing someone pointed out to me, is that you should do
    it when Xcode is not running. Otherwise it can still mysteriously
    remember some things that it's cached.

    Ian.

    On 27/04/2008, at 9:47 PM, Graham Cox wrote:
    >
    > That explains the misalignment of the ivars in the debugger, but it
    > *doesn't* explain the discrepancy between the actual layout of the
    > class in the debugger compared with the latest version of the
    > framework - the debugger was still using a layout which was last
    > current about five weeks ago. That part I still haven't got to the
    > bottom of, though basically throwing every build folder away that I
    > could find and forcing a full rebuild ("clean" didn't do it) finally
    > kicked into using the current version.
    >
    > I'd still like to know more about how all this actually works - I
    > feel I'm groping in the dark when things go wrong.
    >
    > G.
  • On 2008 Apr, 27, at 2:47, Graham Cox wrote:

    > I'd still like to know more about how all this actually works - I
    > feel I'm groping in the dark when things go wrong.

    Graham, welcome to the apparently small club (about 3-4 oddballs) who
    care about what version and configuration of their private framework
    gets packaged or run.  For more info, search xcode-
    <users...> archives for past month or two.  Here are a
    couple of interesting facts to get you started:

    1.  If you set a "Copy Files" Build phase to "Frameworks", Xcode will
    always copy the same Build Configuration regardless of which
    configuration you're building.  I've found it to always copy Release,
    but someone else reported that it always copies Debug.

    2.  Say you set a private framework to build in the normal way, with
    Installation Directory = @executable_path/../Frameworks.  In the app
    project, set the Build Configuration to Debug and Run in Xcode.  The
    framework that gets run is apparently the one in your Builds
    directory, not the one in the app package.  However, if you
    doubleclick the app's Debug build in Finder, it runs the one in the
    app package, which is what I expect it to do in any case. [1]

    The second fact is possibly what is causing the problem you saw
    yesterday.

    Consider putting some tattletale code such as the following in your
    framework.  (Untested code composed in Mail.app)

    Class class = ... ; // Some class defined in your framework
    NSString *msg = [NSString stringWithFormat:
                      @"Class %@ was loaded from %@",
                      class,
                      [[NSBundle bundleForClass:class] bundlePath]] ;

    NSLog(msg) ;

    Anyhow this is more of an Xcode issue so I'd recommend that further
    discussion be done in <xcode-users...>.

    Jerry

    [1] I discovered this by accident yesterday when I had implemented the
    same class in two private frameworks.

    When running in Xcode, I get this message in the Xcode console:

    Class SSLocalizeBundleGetter is implemented in both /Users/jk/
    Documents/Programming/Builds/Debug/SSSQLiter.framework/Versions/A/
    SSSQLiter and /Users/jk/Documents/Programming/Builds/Debug/
    SSLocalize.framework/Versions/A/SSLocalize. Using implementation from /
    Users/jk/Documents/Programming/Builds/Debug/SSLocalize.framework/
    Versions/A/SSLocalize.

    But upon doubleclicking that same build in Finder, I get this message
    in Console.app:

    Class SSLocalizeBundleGetter is implemented in both /Users/jk/
    Documents/Programming/Builds/Debug/MyApp.app/Contents/MacOS/../
    Frameworks/SSSQLiter.framework/Versions/A/SSSQLiter and /Users/jk/
    Documents/Programming/Builds/Debug/MyApp.app/Contents/MacOS/../
    Frameworks/SSLocalize.framework/Versions/A/SSLocalize. Using
    implementation from /Users/jk/Documents/Programming/Builds/Debug/
    MyApp.app/Contents/MacOS/../Frameworks/SSLocalize.framework/Versions/A/
    SSLocalize.
  • On Apr 27, 2008, at 1:43 PM, Jerry Krinock wrote:

    > Graham, welcome to the apparently small club (about 3-4 oddballs)
    > who care about what version and configuration of their private
    > framework gets packaged or run.

    That group includes most everybody.  Everybody wants their tools to
    work, and that includes building and running against the proper
    versions of their frameworks.  Please don't presume that just because
    you have hit difficulties or bugs that it's because you're the only
    one who cares, thanks.

    > For more info, search <xcode-users...> archives for past
    > month or two.  Here are a couple of interesting facts to get you
    > started:
    >
    > 1.  If you set a "Copy Files" Build phase to "Frameworks", Xcode
    > will always copy the same Build Configuration regardless of which
    > configuration you're building.  I've found it to always copy
    > Release, but someone else reported that it always copies Debug.

    A Copy Files build phase will always copy whatever is pointed to by
    the reference you add to the build phase.

    * If that reference comes from another project, and you aren't using a
    shared build directory, that reference will point off into space.  You
    need to ensure you're using a shared build directory if you want to
    use the product from a cross-project reference.

    * If that reference is in a shared build directory and is "build-
    product relative" then you need to ensure it has a path like
    "MyFramework.framework" rather than "../Debug/MyFramework.framework".
    This can happen if your active configuration is Release but you add a
    framework from your shared Debug folder; Xcode will do what you say,
    not what you mean, in that situation, and construct a relative path to
    the Debug folder rather than chop that part off.

    If you've been encountering problems copying embedded frameworks, I
    suspect you fall into one of the two situations above.

    > 2.  Say you set a private framework to build in the normal way, with
    > Installation Directory = @executable_path/../Frameworks.  In the app
    > project, set the Build Configuration to Debug and Run in Xcode.  The
    > framework that gets run is apparently the one in your Builds
    > directory, not the one in the app package.  However, if you
    > doubleclick the app's Debug build in Finder, it runs the one in the
    > app package, which is what I expect it to do in any case. [1]

    This is by design.  When running a build product, Xcode tells dyld to
    first search your built products directory for frameworks and
    libraries that it loads.  This is because often you will want to do
    things like make a change to a framework and then test your
    application against that framework without installing that framework
    wherever it needs to be installed.

    For some people that's "inside the application's embedded Frameworks
    directory" but for others that's "in /Library/Frameworks" - hopefully
    it's clear that what Xcode currently does is a huge win in the latter
    case.

      -- Chris
  • On 2008 Apr, 28, at 21:34, Chris Hanson wrote:

    > On Apr 27, 2008, at 1:43 PM, Jerry Krinock wrote:
    >
    >> Graham, welcome to the apparently small club (about 3-4 oddballs)
    >> who care about what version and configuration of their private
    >> framework gets packaged or run.
    >
    > That group includes most everybody.

    Well, there was not much interest in Xcode-users when we discussed
    this a few weeks ago, but now that the club includes Chris Hanson,
    we're getting somewhere!!!

    > A Copy Files build phase will always copy whatever is pointed to by
    > the reference you add to the build phase.
    >
    > * If that reference comes from another project, and you aren't using
    > a shared build directory, that reference will point off into space.
    > You need to ensure you're using a shared build directory if you want
    > to use the product from a cross-project reference.

    I always use a shared build directory (since you told me to), and when
    adding frameworks, I drag the product from within Groups & Files of
    the project that builds the framework (since this is what Xcode
    documentation says to do).  It seems logical to me, that, unlike
    anything you can find in Finder, this product reference is not
    encumbered with any knowledge of 'build configuration' and therefore
    might be free to switch to the current build configuration, which is
    what I want.  But it doesn't.  And also, when I hover my mouse over
    one of them, I always get a full path to the framework in the shared
    Release build directory.

    > * If that reference is in a shared build directory and is "build-
    > product relative" then you need to ensure it has a path like
    > "MyFramework.framework" rather than "../Debug/MyFramework.framework".

    I've never seen such a path.  Please explain how you see that.
    Whenever I hover my mouse over a framework I've added to Groups &
    Files, the tooltip always shows a full path, no matter if it came from
    Groups & Files or Finder.

    >> 2.  Say you set a private framework to build in the normal way,
    >> with Installation Directory = @executable_path/../Frameworks.  In
    >> the app project, set the Build Configuration to Debug and Run in
    >> Xcode.  The framework that gets run is apparently the one in your
    >> Builds directory, not the one in the app package.  However, if you
    >> doubleclick the app's Debug build in Finder, it runs the one in the
    >> app package, which is what I expect it to do in any case. [1]
    >
    > This is by design.  When running a build product, Xcode tells dyld
    > to first search your built products directory for frameworks and
    > libraries that it loads.  This is because often you will want to do
    > things like make a change to a framework and then test your
    > application against that framework without installing that framework
    > wherever it needs to be installed.
    >
    > For some people that's "inside the application's embedded Frameworks
    > directory" but for others that's "in /Library/Frameworks" -
    > hopefully it's clear that what Xcode currently does is a huge win in
    > the latter case.

    On behalf of all those who have read this far, I thank you for
    explaining that.
previous month april 2008 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        
Go to today
MindNode
MindNode offered a free license !