私は、3週で3回生産を壊しました


先週、私はあなたと共有しました.
それは誰にでも起こることができます、しかし、1つは彼の責任がそのようなイベントにつながることを忘れてはいけません.
我々はテストシステムが役に立たない方法について不満を言うことができます、我々は批評家を非難することができます、しかし、日の終わりに、コードは1人によって書かれました.これらの場合では、私によって.
先週、私はどのように滑って、正しくポインタを初期化しないことで未定義の動作を導入しました.さあ、他の2つのバグで2つの話を続けましょう.

メモリリーク


私が紹介したもう一つの問題は、再びポインターについてでした.非常に知識のあるC +のエンジニアは最近、ダイナミックなメモリ管理のためにスマートポインターを使用しなければならないという理由のために最近私に言いました、しかし、あなたがすべてでダイナミックな配分を使用するのを避けることができるならば、それはさらによいです.
それで、別のモンスタークラスの一つでは、nullptr 初期化子リストでは、いくつかのオブジェクトが多くの異なる場所でそれに割り当てられました、そして、最後に、デストラクタでは、それは削除されませんでした.メモリリーク-私はクリーンアップを逃していない限り.
ポインターを別のオブジェクトに複数回渡し、ポインターオブジェクトを更新してから取り戻しました.
どうも
auto aStatus = STATUS::UNDEFINED;
auto aService = MyService{};
aService.setAdapter(m_serviceAdapter);
try {
  aStatus = aService.resume();
}
catch (std::exception& e) {
  // ...
}
// should now contain the right data!
m_serviceAdapter = static_cast<MyServiceAdapter*>(aService.getAdapter());
すべての問題は、スマートポインタを使用して回避することができます.
非常に簡単なオプションは共有ポインタを使っていたかもしれませんが、2つの理由でそれをしたくなかったのです.
  • MyService 別のリポジトリに住んでいるし、新しいバージョンを変更、レビュー、および配信するには約1日かかる
  • 共有ポインタを使用するほとんどの場合、必要はありません.それは単に取るために簡単な道です.私は、より簡単な道を行きたくありませんでした.
  • それで、私はユニークなポインタを使い続けました.m_serviceAdapter になったstd::unique_ptr<MyServiceAdapter> の代わりにMyServiceAdapter* そして、次のようにコードを変更しました.
    auto aStatus = STATUS::UNDEFINED;
    auto aService = MyService{};
    aService.setAdapter(m_serviceAdapter.release()); // 1
    try {
      aStatus = aService.resume();
    }
    catch (std::exception& e) {
      // ...
    }
    // should now contain the right data!
    m_serviceAdapter.reset(static_cast<MyServiceAdapter*>(aService.getAdapter())); //2
    
    私の推論は// 1 , 我々はサービスアダプタをもう所有したくありません、我々はサービスに所有権を渡します.
    アットステップ// 2 , ローカルアダプタを他のサービスアダプタからリセットします.すべて結構ですね.
    ステップ1で我々は所有権をリリースし、ステップ2で我々はそれを取り戻した.
    何が間違って行くことができますか?
    ifMyServiceAdapter 別のポインタを割り当てます.それはメモリリークですが、それは問題ですMyServiceAdapter , 呼び出し場所ででない.
    それで、我々はすべてがすばらしいと主張することができました.
    上記パターンには5〜6の機能があった.しかし、リリース部分だけがあったもう一つのリセットがありませんでした.
    そして、これで、私は明らかにメモリリークを導入し、それがフォールバックを必要とした!
    それで、小さいメモリリークから、我々はより大きなものに行きましたか?
    それは私がまだ理解していない何かです.私は、上記の変更で、私はメモリリークを減らすべきであると思います.しかし、生産統計は非常に明確であった.
    第2号の取材
  • メモリ管理に関しては、慎重にしてください.
  • 半分の解決法に従わないでください.あなたが所有権を渡すと仮定する場合は、チェーンを通してすべての方法を移動し、全体の流れを修正します.
  • より多くのあなたの割り当てられたメモリに起こることを理解するために、より多くのvalgrindを使用してください.
  • 知っているツール


    この最後の1つは短く、おそらく少し技術的になります.このミームをご存知ですか?
    Works - does not work
    私は、これが素晴らしいものであると思います、そして、あなたが下半分で見ることができるものは実際に非常に頻繁な状況です.
    なぜ私はそう言うのですか?
    あなたは動作しないコードの一部を持っているし、理由がわからない.それから、あなたはそれを修正します.
  • あなたも、それを考えますか?なぜそれが機能を理解するか?
  • もしそうなら、素晴らしい!しかし、どうですか?あなたは調査を続けますか.または単に次の問題に移動しますか?
  • 私は判断するためにここにいない.多くの場合、我々は調査を継続する時間がないし、我々はパイプのものを取る必要があります.しかし、それは重大な含意を持っています.
    多くの場合、それは良い解決策であるため、機能は機能しません.私は、それを良い十分な解決とさえ呼びません.時にはそれは、特定の状況下で動作するだけで脆い修理ですが、それはいつでも破ることができます.
    C +はまだ事実上の標準であるビルド管理システムを持っていません、多くの会社は私たちのように彼ら自身のものを持っています.したがって、私は何が起こったかの深い技術的な詳細に入らないでしょう、しかし、私はあなたにより高い見解を与えます.
    いくつかの依存関係はパッケージにグループ化され、私たちのディスクリプタに必要な更新を行いました.我々はすでにアルファベット順にリストされたいくつかのパッケージに依存していた.ところで、2つの最も重要なパッケージは、このソートの始めに起こりました.
    それで、依存関係をアップデートして、パッケージをそのアルファベットの場所に置きました.みんな元気だった.
    テストシステムにロードしました.誰も一言も語らなかった.
    その後、我々は生産にロードしました.人々は文句を言い始めた.
    我々は統計コレクタを破った.
    我々はすぐに負荷から来ているので、我々はフォールバックしたことが分かった.しかし、それは何ですか?
    私は重要でハイリスクの変化の準備をしていました、そして、私はルーチンバージョンアップデートとそれを混同したくありませんでした.
    それも我々のソフトウェアを壊したか.
    二つのことを変えました.
  • 私は依存のいくつかのバージョンを更新しました
  • そして、私は我々がそれらの正確な同じ依存症をとるところから変わりました.
  • 私はリリースノートをチェックしました.何もない.
    私はパッケージのメンテナとチェックインしました.
    私はビルド管理システムのドキュメントをチェックしました.
    しかし、私たちが考えていなかったので、私たちは秩序とLOを変えました.
    含まれている依存関係の順序は、いくつかの非マッチングバージョンを解決するときに重要です.
    多くのことが、この調査をよりしていたより苦しいものにした.
  • ユーザーのためのテストで既に見えていたにもかかわらず、問題は生産負荷の前には気づかなかった
  • それは地方で再現性がないので、毎日新しい何かを試す機会が非常に限られていました
  • ドキュメントは明らかにどのようにバージョンが推論されて不完全です
  • レッスンは何ですか?
  • 物事はチャンスよりも頻繁に考えるだけで動作します
  • あなたが次のレベルに成長したい場合は、ツールを理解するために時間がかかる
  • あなたの変更について不明な場合は、赤ちゃんの手順を実行し、できるだけ早くそれらを検証します.
  • 結論


    しばしば、物事は偶然に働いていると、彼らはいつでも破ることができます!あなたが最善の意図でそれらを破ることができる場合でも、あなたが技術的な改善を検討するいくつかの変更を導入すると思います.私はさらに行きます、それらがシステムを壊す最も簡単である瞬間ですあなたが改善を提供していると確信しているとき.
    私のアドバイスは、正確にあなたが何をしているかを理解するために時間がかかることであり、赤ちゃんのステップを取ることを恐れていないです.反復が小さいほど、理解しデバッグすることが容易になります.
    そして、たわごとが起こるならば、落胆させないでください.システムを改善し続けてください!

    接続深い


    この記事が好きなら
  • ボタンのようにヒット

  • subscribe to my newsletter
  • そして、接続しましょう!