Skip to content

Commit

Permalink
Add a pass to insert artificial debug info when the method miss it
Browse files Browse the repository at this point in the history
Reviewed By: NTillmann

Differential Revision: D66043130

fbshipit-source-id: 6d07d03399b5c75e0e86291a61feb30e5ffdf070
  • Loading branch information
ssj933 authored and facebook-github-bot committed Nov 26, 2024
1 parent 888b34d commit 92634c4
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ libopt_la_SOURCES = \
opt/final_inline/FinalInlineV2.cpp \
opt/fully-qualify-layouts/FullyQualifyLayouts.cpp \
opt/init-classes/InitClassLoweringPass.cpp \
opt/insert_debug_info/InsertDebugInfoPass.cpp \
opt/insert-source-blocks/InsertSourceBlocks.cpp \
opt/instrument/BlockInstrument.cpp \
opt/instrument/Instrument.cpp \
Expand Down
60 changes: 60 additions & 0 deletions opt/insert_debug_info/InsertDebugInfoPass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#include "InsertDebugInfoPass.h"

#include "ControlFlow.h"
#include "PassManager.h"
#include "Show.h"
#include "Walkers.h"

void InsertDebugInfoPass::run_pass(DexStoresVector& stores,
ConfigFiles& conf,
PassManager& mgr) {
std::atomic<uint32_t> patched_method = 0;
walk::parallel::code(
build_class_scope(stores), [&](DexMethod* method, IRCode& code) {
always_assert(code.editable_cfg_built());
bool has_position = false;
auto& cfg = code.cfg();
for (auto* block : cfg.blocks()) {
for (auto it = block->begin(); it != block->end(); it++) {
if (it->type == MFLOW_POSITION) {
has_position = true;
break;
}
}
}
if (has_position) {
return;
}
patched_method++;
always_assert_log(!code.get_debug_item(),
"%s has no DexPosition, but has a DexDebugItem %s",
SHOW(method),
SHOW(code.cfg()));
code.set_debug_item(std::make_unique<DexDebugItem>());
auto* block = cfg.entry_block();
auto last_param = block->get_last_param_loading_insn();
auto artificial_pos = std::make_unique<DexPosition>(
DexString::make_string(show_deobfuscated(method)),
DexString::make_string("UnknownSource"), 0);
if (last_param == block->end()) {
cfg.insert_before(block->to_cfg_instruction_iterator(
block->get_first_non_param_loading_insn()),
std::move(artificial_pos));
} else {
cfg.insert_after(block->to_cfg_instruction_iterator(
block->get_last_param_loading_insn()),
std::move(artificial_pos));
}
});

mgr.set_metric("patched_method", patched_method);
}

static InsertDebugInfoPass s_pass;
27 changes: 27 additions & 0 deletions opt/insert_debug_info/InsertDebugInfoPass.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include "Pass.h"

class InsertDebugInfoPass : public Pass {
public:
InsertDebugInfoPass() : Pass("InsertDebugInfoPass") {}

redex_properties::PropertyInteractions get_property_interactions()
const override {
using namespace redex_properties::interactions;
using namespace redex_properties::names;
return {
{DexLimitsObeyed, Preserves},
{UltralightCodePatterns, Preserves},
};
}

void run_pass(DexStoresVector&, ConfigFiles&, PassManager&) override;
};

0 comments on commit 92634c4

Please sign in to comment.