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
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
How I Won Prize Money at a Hackathon Using Codex and Symphony Alpha
yasei_no_otoko
0
130
承認済みなのに差戻しできてしまうバグ、型で潰せます
shinchit
0
120
Introducing Stack Pull Request in GitHub
kkamegawa
0
110
freee が目指す データ マネジメント戦略 AI-Ready 時代を支える 攻めのガバナンスとは
freee
PRO
0
530
仕様駆動開発の消費期限
watany
20
9.1k
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
7.9k
プロポーザルを書いてもらう
pvcresin
0
590
不幸な GC
chencmd
0
820
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
1
2k
My Marp Sample
sinoue0108
0
130
Webエンジニアなのにブラウザの仕組みがわからないので、Pythonで自作してみた
tatsuki12
4
1.2k
Go を使い始めて 2 ヶ月の学び / My first two months with Go
contour_gara
0
400
Featured
See All Featured
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
840
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
590
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
390
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
Making the Leap to Tech Lead
cromwellryan
135
10k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
690
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
From π to Pie charts
rasagy
0
330
Ethics towards AI in product and experience design
skipperchong
2
350
It's Worth the Effort
3n
188
29k
Raft: Consensus for Rubyists
vanstee
141
7.7k
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
🦙