Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
LLDBを活用したデザインチェック
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Suita Fujino
June 23, 2021
Programming
2.5k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
LLDBを活用したデザインチェック
potatotips #74 (2021/6/23)
GitHub:
https://github.com/Scior/LLDBVisualDebug
Suita Fujino
June 23, 2021
Other Decks in Programming
See All in Programming
これからAgentCoreを触る方へトレンドはGatewayです
har1101
6
490
地域 SRE コミュニティ最前線 - ホンマでっかSRE勉強会
tk3fftk
0
230
「正の参照」と 「負の導出」で組む ハーネスエンジニアリング
cottpan
1
140
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
言語を使う側から、作る側へ。 自作 Lisp で得た新たな気づき。
andpad
0
120
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
170
なぜ型を書くのか? TSKaigi2026で改めて考える #tskaigi_smarthr
kajitack
0
370
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
0
110
Claude Team Plan導入・ガイド
tk3fftk
0
200
Haskell/Servantを通してWebミドルウェアを捉え直す
pizzacat83
1
580
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
2
1.5k
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
320
Featured
See All Featured
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
770
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
New Earth Scene 8
popppiees
3
2.4k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
360
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
Practical Orchestrator
shlominoach
191
11k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
1
3.7k
The Limits of Empathy - UXLibs8
cassininazir
1
500
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.3k
Building AI with AI
inesmontani
PRO
1
1.1k
Transcript
(@Scior) LLDB Swift Python 1
AppBrew LIPS iOS PjM ( Keynote) ࣗݾհ🦙 ෩ܠ͖֯ͷਓू·Εʙ📷
None
(lldb) e view.isHidden = false
Google UI
Python
None
( )
UIView Save
UIView UIView Data UIGraphicsImageRenderer SBProcess.ReadMemory Lib/io LLDB
(lldb) saveimage imageView /tmp/alpaca.png
Swift ( ) loadext DebugExtensions.swift evaluate DebugExtensions.swift
Swift (loadext) @lldb.command("loadext") def load(debugger, command, result, dict): path =
os.path.join(os.path.dirname(__file__), 'swift/DebugExtensions.swift') with open(path, 'r') as f: common.evaluate(f.read()) * common.evaluate
DebugExtensions.swift extension UIView { func takeSnapshot() -> UIImage? { let
renderer = UIGraphicsImageRenderer(bounds: bounds) return renderer.image { context in layer.render(in: context.cgContext) } } func convertToPNGData() -> Data { return takeSnapshot()!.pngData()! } } ͪΖΜ#if DEBUG ~ #endifͰғͬͯίϯύΠϧͯ͠ྑ͍
saveimage ( ) saveimage convertToPNGData() evaluate convertToPNGData() DebugExtensions.swift
saveimage ( ) saveimage address size convertToPNGData() evaluate convertToPNGData() Data
SBValue DebugExtensions.swift
saveimage ( ) @lldb.command("saveimage") def save_image(debugger, arguments, result, dict): view,
path = arguments.split() var_name = str(uuid.uuid4()).replace('-', '') common.evaluate('let $%s = %s.convertToPNGData()' % (var_name, view)) address_str = common.evaluate('($%s as NSData).bytes' % var_name).GetObjectDescription().split()[1] address = int(address_str, 16) size = int(common.evaluate('$%s.count' % var_name).GetValue()) process = lldb.debugger.GetSelectedTarget().GetProcess() error = lldb.SBError() data = process.ReadMemory(address, size, error) with open(path, "wb") as f: f.write(data)
@lldb.command("saveimage") def save_image(debugger, arguments, result, dict): @lldb.command command script add
-f LLDB
convertToPNGData() common.evaluate('let $%s = %s.convertToPNGData()' % (var_name, view)) let $hoge
= imageView.convertToPNGData()
Data address_str = common.evaluate('($%s as NSData).bytes' % var_name).GetObjectDescription().split()[1] address =
int(address_str, 16) size = int(common.evaluate('$%s.count' % var_name).GetValue()) ($hoge as NSData).bytes $hoge.count (Obj-C++ )
process = lldb.debugger.GetSelectedTarget().GetProcess() error = lldb.SBError() data = process.ReadMemory(address, size,
error) with open(path, "wb") as f: f.write(data) SBProcess.ReadMemory Python
* GitHub
( )
UIView Overlay
UIView Data UIImage UnsafeMutablePointer UIImage.init(data:) Lib/io SBProcess.WriteMemory LLDB
(lldb) overlayimage imageView /tmp/alpaca.png
ImageBuffer final class ImageBuffer { typealias Pointer = UnsafeMutablePointer<UInt8> private
let size: Int let pointer: Pointer init(size: Int) { self.size = size pointer = Pointer.allocate(capacity: size) } deinit { pointer.deallocate() } func getData() -> Data { let bufferPointer = UnsafeMutableBufferPointer(start: pointer, count: size) return .init(buffer: bufferPointer) } }
overlayimage @lldb.command("overlayimage") def overlay_image(debugger, arguments, result, dict): view, path =
arguments.split() with open(path, 'rb') as f: data = f.read() buf_name = common.generateVarName() common.evaluate('let $%s = ImageBuffer(size: %s)' % (buf_name, len(data))) address_str = common.evaluate('$%s.pointer' % buf_name).GetObjectDescription().split()[1] address = int(address_str, 16) process = lldb.debugger.GetSelectedTarget().GetProcess() error = lldb.SBError() size = process.WriteMemory(address, data, error) view_name = common.generateVarName() common.evaluate('let $%s = DebugOverlayView(frame: %s.frame)' % (view_name, view)) common.evaluate('$%s.set(data: $%s.getData())' % (view_name, buf_name)) common.evaluate(‘%s.superview?.addSubview($%s)' % (view, view_name))
with open(path, 'rb') as f: data = f.read() common.evaluate('let $%s
= ImageBuffer(size: %s)' % (buf_name, len(data))) address_str = common.evaluate('$%s.pointer' % buf_name).GetObjectDescription().split()[1] address = int(address_str, 16) ImageBuffer
process = lldb.debugger.GetSelectedTarget().GetProcess() error = lldb.SBError() size = process.WriteMemory(address, data,
error) SBProcess.WriteMemory
View common.evaluate('let $%s = DebugOverlayView(frame: %s.frame)' % (view_name, view)) common.evaluate('$%s.set(data:
$%s.getData())' % (view_name, buf_name)) common.evaluate(‘%s.superview?.addSubview($%s)' % (view, view_name)) let $view = DebugOverlayView(frame: view.frame) $view.set(data: $buf.getData()) view.superview?.addSubview($view)
☺ * GitHub
With OpenCV and scikit-image (in progress) View cv skimage (UILabel
)
https://github.com/Scior/LLDBVisualDebug
Appendix
common.evaluate def evaluate(exp): options = lldb.SBExpressionOptions() options.SetLanguage(lldb.eLanguageTypeSwift) frame = (
lldb.debugger.GetSelectedTarget() .GetProcess() .GetSelectedThread() .GetSelectedFrame() ) return frame.EvaluateExpression(exp, options)
LLDB Python API: https://lldb.llvm.org/python_api.html facebook/chisel: https://github.com/facebook/chisel
🦙