Github is open source, step by step

One, foreword

Some time ago, our project also implemented the binarization of components. In the previous technical weekly meeting, we mentioned the binary debugging capability of the same ZSource as Meituan.com. We also implemented the same function pod bin code on our Cocoapods- Imy-bin plug-in. With the help of this weekly session, we’ll take another look at how binary debugging is implemented and how the pod Bin Code plug-in is implemented.

Two, the effect demonstration

Third, the principle of

Use the MachOViewer to view binary files to get more binary friendly information. Using the MachOViewer, we can see that the “__debug_str” Section has all the information stored in the binary. __debug_str internally records the source address at compile time

Using the command on the terminal, enter:

dwarfdump ./libIMYNews.a | grep 'IMYNewsRootViewController'
Copy the code

A DW_AT_name attribute whose value is a null-terminated string containing the full or relative pathname of the primary source file from which the compilation unit is derived.

A DW_AT_comp_dir attribute whose value is a null-terminated string containing the current working directory of the compilation command that, in some form, treats Forelax as the host system to generate this compilation unit.

In plain English, the binary file records the corresponding location of the source file, imybutton. m source file exists in this address

/Users/ci/.jenkins/workspace/Meetyou_Dev-build-temp/bin-archive/Seeyou/IMYNews/IMYNews/Source/IMYNewsRootView/Controller /IMYNewsRootViewController.hCopy the code

And what is this address? It’s actually the location of the file where the project was when we made the binary package.

When debugging, the compiler will first load the source file from this mapping address. If there is a corresponding address exists when the source file, you can enter the source debugging.

What if you don’t want to expose this debugging information? Search for Generate Debug Symbols in build Settings and set it to No to remove the __debug_STR field.

Four, the

Some students here may wonder whether your debugging information is different from our usual debugging information, and it is not accurate enough.

Experiment 1, Xcode source running debugging

Now let’s do an experiment to see what normal Debug is like.

  1. Use the source code to run normally, in a line next to a breakpoint, to see the normal debugging situation
  2. Rename the file directory where the current breakpoint is located to another path
  3. Run to the breakpoint again try, can you also enter the source code as in step 1 to debug the breakpoint? (Obviously not)
  4. Change back to the directory renamed in step 2, and then Control+F7 to run, this time it is normal again, or you know the original she.

Even when the source code is running, Xcode is debugged according to our principles.

Experiment 2: Generate Debug Symbols set to No

With the source code running, I set the IMYNews module Generate Debug Symbols to No, and No matter how hard I try, the breakpoint won’t get there

Five, source debugging Cocoapods plug-in implementation

We know from the above principle analysis that as long as there is a binary static library record source corresponding file can enter the breakpoint debugging, but Pods warehouse source in remote how to debug? How do I know which version of the static library I am running?

Familiar with some principles of Cocoapods, find out the library code on this few lines.

# Find dependencies
def find_dependency (name)
    find_dependency = nil
    @config.podfile.dependencies.each do |dependency|
    if dependency.root_name.downcase == name.downcase
      find_dependency = dependency
          break
      end
     end
     find_dependency
 end

Select * from external_source
# @return spec
def fetch_external_source(dependency ,podfile , lockfile, sandbox,use_lockfile_options)
          source = 			ExternalSources.from_dependency(dependency, podfile.defined_in_file, true)
          source.fetch(sandbox)
end
Copy the code

Download the corresponding source code

Download source code to local
def download_source(name)
  target_path =  File.join(source_root, name)
  UI.puts target_path
  FileUtils.rm_rf(target_path)
  
  find_dependency = find_dependency(name)
  spec = fetch_external_source(find_dependency, @config.podfile,@config.lockfile, @config.sandbox,true )
  download_request = Pod::Downloader::Request.new(:name => name, :spec => spec)
  Downloader.download(download_request, Pathname.new(target_path), :can_cache= >true)

  target_path
end
Copy the code

Creating a soft link

ln -s target_path dir
Copy the code

Vi. Finally:

Some things like magic, the audience to see the clouds in the fog, in fact, after breaking, there will be a feeling, the original is just such a thing ~.

Vii. References

IOS Xcode assembly mode switch

Behind the Zsource command for Meituan’s iOS project


There is a shortage of all kinds of talents, welcome to join the big family of beautiful grapefruit.

Send your resume to [email protected]