omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Mysterious Crash

    Pythonista
    3
    7
    4779
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • blmacbeth
      blmacbeth last edited by

      I have a script where I'm trying to get the system attributes; eventually this will gather memory information. I have isolated the crash to this line of code:

      from ctypes import POINTER
      from objc_util import ObjCClass, ObjCInstance, c, c_void_p
      
      
      NSHomeDirectory = c.NSHomeDirectory
      NSHomeDirectory.restype = c_void_p
      NSHomeDirectory.argtype = []
      
      NSFileManager = ObjCClass('NSFileManager')
      
      LP_c_void_p = POINTER(c_void_p)
      
      def get_system_attributes():
      	file_manager = NSFileManager.defaultManager()
      	error = LP_c_void_p()
      	attributes = file_manager.attributesOfFileSystemForPath_error_(
      		ObjCInstance(
      			NSHomeDirectory()
      		).cString(),
      		error
      	)
      	return attributes
      
      get_system_attributes()
      

      attributesOfFileSystemForPath_error_ takes a string and an error pointer. It crashes when it gets to the error inside that function. I think it crashes due to an NSError object being created. Any ideas on how to stop the crash?

      1 Reply Last reply Reply Quote 0
      • omz
        omz last edited by

        The crash seems to come from your cString() call. The method expects an NSString object, and you already have that, so simply removing .cString() should fix the crash.

        1 Reply Last reply Reply Quote 0
        • omz
          omz last edited by

          Btw, if you're not actually interested in the error, you can also just pass None for that (you could still detect failure by checking if the return value is None; you only need the error pointer if you want details about the failure).

          1 Reply Last reply Reply Quote 0
          • Cethric
            Cethric last edited by

            To add on to what @omz said I also saw a crash with the error variable as well.
            Here is my fix:

            path = ObjCInstance(NSHomeDirectory())
            file_manager = NSFileManager.defaultManager()
            error = c_void_p()
            a = file_manager.attributesOfFileSystemForPath_error_(path, pointer(error))
            print(ObjCInstance(error))
            print(a)
            

            The only major change that I made was to use ctypes.pointer instead of ctypes.POINTER as the upper case version is for defining argtypes and restypes or values in structures where as the lower case version is used for creating pointer objects

            1 Reply Last reply Reply Quote 0
            • omz
              omz last edited by

              @Cethric I think byref(error) would be a little faster (at least that's what the ctypes docs say).

              1 Reply Last reply Reply Quote 0
              • Cethric
                Cethric last edited by

                Good catch, I can't say I have done a speed test on iOS to see the differences between the two, but in general yes byref(error) is faster than pointer(error)

                1 Reply Last reply Reply Quote 0
                • blmacbeth
                  blmacbeth last edited by

                  @omz and @Cethric thanks for the help. It seems to work.

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post
                  Powered by NodeBB Forums | Contributors