12

Is there a way in lldb to overwrite a readonly variable.

For example if you had a struct

struct Object {
    let name: String
}

Doing the following in at a breakpoint in Xcode with lldb

(lldb) expression object.name = "Tom"

Will result in

error: <EXPR>:2:19: error: cannot assign to property: 'name' is a get-only property

I fully understand why this happens, just want to know if there is an easy way to get around this during debugging?

Please note this is in Swift & NOT Objective-C

3
  • Why do you need to overwrite a readonly variable? Since you know you can not change the name of a Object, why do not you initialize a new Object rather than change the name of it? Commented Sep 1, 2016 at 6:18
  • 1
    @Joe because when you are debugging and using lldb it is often useful to change one variable at runtime to test different behaviors. If you have a complex object that requires dependency injection simply allocating a new object becomes more complex in your console. Commented Sep 1, 2016 at 14:40
  • So why not change the let to var? Commented Sep 6, 2016 at 15:33

1 Answer 1

5
+25

You can use the memory write {address} lldb command to overwrite the memory and change the string value. I managed to do it one address at a time, but it seems like memory write is capable of doing it one go.

(lldb) help memory write
     Write to the memory of the process being debugged.

Syntax: memory write <cmd-options> <address> <value> [<value> [...]]

Command Options Usage:
  memory write [-f <format>] [-s <byte-size>] <address> <value> [<value> [...]]
  memory write -i <filename> [-s <byte-size>] [-o <offset>] <address> <value> [<value> [...]]

       -f <format> ( --format <format> )
            Specify a format to be used for display.

       -i <filename> ( --infile <filename> )
            Write memory using the contents of a file.

       -o <offset> ( --offset <offset> )
            Start writing bytes from an offset within the input file.

       -s <byte-size> ( --size <byte-size> )
            The size in bytes to use when displaying with the selected format.

     This command takes options and free-form arguments.  If your arguments
     resemble option specifiers (i.e., they start with a - or --), you must use
     ' -- ' between the end of the command options and the beginning of the
     arguments.

Here's an example (hopefully someone with more understanding of the lldb and the internals of Swift can provide a better method):

Example using memory write

This shows overwriting the memory one byte at a time. po "Tom".dataUsingEncoding(NSUTF8StringEncoding)! gets the hex representation, which is used to step through and overwrite the memory of object.name. I'm sure there's an easier way to do it (in one command), but I couldn't figure out the correct parameter values to pull it off.

Sign up to request clarification or add additional context in comments.

4 Comments

The syntax to replace all the bytes at once is memory write <address> <size> <byte> <byte> ..., so for example memory write 0x1000022c0 -s 1 66 6F 6F 62 61 72...
Interesting solution, not ideal but seems to work, thanks.
@l'L'l Thanks for the answer to that, I was trying something like memory write 0x1000022c0 -s 6 666F6F626172 which didn't work. @sbarow Thanks for accepting, it is a pretty cumbersome solution.
You might also be able to write a string directly using the -f switch: memory write -f s -s <numbytes> -- "Hello, world" Not sure, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.