Global Metrics

path: .metrics.cognitive.sum
old: 0.0
new: 17.0

path: .metrics.cognitive.average
old: 0.0
new: 3.4

path: .metrics.nexits.average
old: 1.0
new: 0.6

path: .metrics.nexits.sum
old: 4.0
new: 3.0

path: .metrics.mi.mi_original
old: 53.78012964130379
new: 44.28162675111616

path: .metrics.mi.mi_sei
old: 30.154909634122085
new: 19.007002779927515

path: .metrics.mi.mi_visual_studio
old: 31.45036821128876
new: 25.895688158547465

path: .metrics.halstead.bugs
old: 0.24649619175541648
new: 0.7968963803500304

path: .metrics.halstead.N1
old: 178.0
new: 286.0

path: .metrics.halstead.estimated_program_length
old: 722.9889779116002
new: 757.0128009163975

path: .metrics.halstead.vocabulary
old: 115.0
new: 123.0

path: .metrics.halstead.level
old: 0.10416666666666669
new: 0.02987446368981408

path: .metrics.halstead.effort
old: 20109.311573654195
new: 116891.9660765756

path: .metrics.halstead.purity_ratio
old: 2.362709078142484
new: 1.5049956280644086

path: .metrics.halstead.n1
old: 15.0
new: 29.0

path: .metrics.halstead.volume
old: 2094.719955588979
new: 3492.0847961856375

path: .metrics.halstead.time
old: 1117.183976314122
new: 6493.998115365312

path: .metrics.halstead.difficulty
old: 9.6
new: 33.473404255319146

path: .metrics.halstead.N2
old: 128.0
new: 217.0

path: .metrics.halstead.n2
old: 100.0
new: 94.0

path: .metrics.halstead.length
old: 306.0
new: 503.0

path: .metrics.cyclomatic.average
old: 1.0
new: 2.3333333333333335

path: .metrics.cyclomatic.sum
old: 11.0
new: 21.0

path: .metrics.nom.functions
old: 4.0
new: 5.0

path: .metrics.nom.total
old: 4.0
new: 5.0

path: .metrics.loc.blank
old: 27.0
new: 16.0

path: .metrics.loc.ploc
old: 61.0
new: 98.0

path: .metrics.loc.sloc
old: 102.0
new: 135.0

path: .metrics.loc.lloc
old: 4.0
new: 39.0

path: .metrics.loc.cloc
old: 14.0
new: 21.0

Spaces Data

Minimal test - lines (27, 36)

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.level
old: null
new: 0.2909090909090909

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.bugs
old: 0.0
new: 0.01511298553975019

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N1
old: 0.0
new: 13.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.volume
old: 0.0
new: 88.81055323538621

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.n1
old: 0.0
new: 5.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.time
old: 0.0
new: 16.96034870814667

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: null
new: 35.60964047443681

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.length
old: 1.0
new: 24.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.n2
old: 1.0
new: 8.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.purity_ratio
old: null
new: 1.4837350197682004

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.vocabulary
old: 1.0
new: 13.0

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.difficulty
old: 0.0
new: 3.4375

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.effort
old: 0.0
new: 305.2862767466401

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N2
old: 1.0
new: 11.0

path: .spaces[0].spaces[0].spaces[0].metrics.nargs.average
old: null
new: 0.0

path: .spaces[0].spaces[0].spaces[0].metrics.loc.blank
old: 0.0
new: 2.0

path: .spaces[0].spaces[0].spaces[0].metrics.loc.ploc
old: 1.0
new: 8.0

path: .spaces[0].spaces[0].spaces[0].metrics.loc.sloc
old: 1.0
new: 10.0

path: .spaces[0].spaces[0].spaces[0].metrics.cognitive.average
old: null
new: 0.0

path: .spaces[0].spaces[0].spaces[0].metrics.nexits.average
old: null
new: 0.0

path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_sei
old: null
new: 82.83693694426118

path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_original
old: null
new: 109.6782929679723

path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: null
new: 64.1393526128493

path: .spaces[0].spaces[0].spaces[0].metrics.nom.total
old: 0.0
new: 2.0

path: .spaces[0].spaces[0].spaces[0].metrics.nom.functions
old: 0.0
new: 2.0

path: .spaces[0].spaces[0].spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 3.0

Code

class LSPAnnotationGatherer : public Runnable {
  ~LSPAnnotationGatherer() {}

 public:
  LSPAnnotationGatherer() : Runnable("crashreporter::LSPAnnotationGatherer") {}
  NS_DECL_NSIRUNNABLE

  void Annotate();
  nsCString mString;
};

Minimal test - lines (48, 127)

path: .spaces[0].spaces[0].spaces[2].metrics.cyclomatic.average
old: 1.0
new: 10.0

path: .spaces[0].spaces[0].spaces[2].metrics.cyclomatic.sum
old: 1.0
new: 10.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.difficulty
old: 0.0
new: 31.753846153846155

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.n2
old: 1.0
new: 65.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.time
old: 0.0
new: 4626.662469755069

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.volume
old: 0.0
new: 2622.672039541391

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.bugs
old: 0.0
new: 0.6356806039273856

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.length
old: 1.0
new: 405.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.N1
old: 0.0
new: 233.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.N2
old: 1.0
new: 172.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.effort
old: 0.0
new: 83279.92445559124

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.level
old: null
new: 0.031492248062015504

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.n1
old: 0.0
new: 24.0

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.purity_ratio
old: null
new: 1.2382543404053266

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.estimated_program_length
old: null
new: 501.4930078641573

path: .spaces[0].spaces[0].spaces[2].metrics.halstead.vocabulary
old: 1.0
new: 89.0

path: .spaces[0].spaces[0].spaces[2].metrics.cognitive.average
old: null
new: 15.0

path: .spaces[0].spaces[0].spaces[2].metrics.cognitive.sum
old: 0.0
new: 15.0

path: .spaces[0].spaces[0].spaces[2].metrics.nexits.sum
old: 0.0
new: 3.0

path: .spaces[0].spaces[0].spaces[2].metrics.nexits.average
old: null
new: 3.0

path: .spaces[0].spaces[0].spaces[2].metrics.nom.total
old: 0.0
new: 1.0

path: .spaces[0].spaces[0].spaces[2].metrics.nom.functions
old: 0.0
new: 1.0

path: .spaces[0].spaces[0].spaces[2].metrics.loc.ploc
old: 1.0
new: 64.0

path: .spaces[0].spaces[0].spaces[2].metrics.loc.sloc
old: 1.0
new: 80.0

path: .spaces[0].spaces[0].spaces[2].metrics.loc.blank
old: 0.0
new: 8.0

path: .spaces[0].spaces[0].spaces[2].metrics.loc.lloc
old: 0.0
new: 36.0

path: .spaces[0].spaces[0].spaces[2].metrics.loc.cloc
old: 0.0
new: 8.0

path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_original
old: null
new: 56.77703403304346

path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_visual_studio
old: null
new: 33.20294387897279

path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_sei
old: null
new: 30.75608415683253

path: .spaces[0].spaces[0].spaces[2].metrics.nargs.average
old: null
new: 0.0

Code

LSPAnnotationGatherer::Run() {
  DWORD size = 0;
  int err;
  // Get the size of the buffer we need
  if (SOCKET_ERROR != WSCEnumProtocols(nullptr, nullptr, &size, &err) ||
      err != WSAENOBUFS) {
    // Er, what?
    MOZ_ASSERT_UNREACHABLE(
        "WSCEnumProtocols succeeded when it should have "
        "failed");
    return NS_ERROR_FAILURE;
  }

  auto byteArray = MakeUnique(size);
  WSAPROTOCOL_INFOW* providers =
      reinterpret_cast(byteArray.get());

  int n = WSCEnumProtocols(nullptr, providers, &size, &err);
  if (n == SOCKET_ERROR) {
    // Lame. We provided the right size buffer; we'll just give up now.
    NS_WARNING("Could not get LSP list");
    return NS_ERROR_FAILURE;
  }

  nsCString str;
  for (int i = 0; i < n; i++) {
    AppendUTF16toUTF8(nsDependentString(providers[i].szProtocol), str);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iVersion);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iAddressFamily);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iSocketType);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iProtocol);
    str.AppendLiteral(" : ");
    str.AppendPrintf("0x%x", providers[i].dwServiceFlags1);
    str.AppendLiteral(" : ");
    str.AppendPrintf("0x%x", providers[i].dwProviderFlags);
    str.AppendLiteral(" : ");

    wchar_t path[MAX_PATH];
    int pathLen = MAX_PATH;
    if (!WSCGetProviderPath(&providers[i].ProviderId, path, &pathLen, &err)) {
      AppendUTF16toUTF8(nsDependentString(path), str);
    }

    str.AppendLiteral(" : ");
    // Call WSCGetProviderInfo to obtain the category flags for this provider.
    // When present, these flags inform Windows as to which order to chain the
    // providers.
    DWORD categoryInfo;
    size_t categoryInfoSize = sizeof(categoryInfo);
    if (!WSCGetProviderInfo(&providers[i].ProviderId, ProviderInfoLspCategories,
                            (PBYTE)&categoryInfo, &categoryInfoSize, 0, &err)) {
      str.AppendPrintf("0x%lx", categoryInfo);
    }

    str.AppendLiteral(" : ");
    if (providers[i].ProtocolChain.ChainLen <= BASE_PROTOCOL) {
      // If we're dealing with a catalog entry that identifies an individual
      // base or layer provider, log its provider GUID.
      RPC_CSTR provIdStr = nullptr;
      if (UuidToStringA(&providers[i].ProviderId, &provIdStr) == RPC_S_OK) {
        str.Append(reinterpret_cast(provIdStr));
        RpcStringFreeA(&provIdStr);
      }
    }

    if (i + 1 != n) {
      str.AppendLiteral(" \n ");
    }
  }

  mString = str;
  NS_DispatchToMainThread(
      NewRunnableMethod("crashreporter::LSPAnnotationGatherer::Annotate", this,
                        &LSPAnnotationGatherer::Annotate));
  return NS_OK;
}

Minimal test - lines (129, 132)

path: .spaces[0].spaces[0].spaces[3].metrics.loc.ploc
old: 47.0
new: 4.0

path: .spaces[0].spaces[0].spaces[3].metrics.loc.blank
old: 24.0
new: 0.0

path: .spaces[0].spaces[0].spaces[3].metrics.loc.sloc
old: 72.0
new: 4.0

path: .spaces[0].spaces[0].spaces[3].metrics.loc.lloc
old: 4.0
new: 1.0

path: .spaces[0].spaces[0].spaces[3].metrics.loc.cloc
old: 1.0
new: 0.0

path: .spaces[0].spaces[0].spaces[3].metrics.cyclomatic.sum
old: 5.0
new: 1.0

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.bugs
old: 0.23298920909552231
new: 0.017335926907505787

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.level
old: 0.10621468926553672
new: 0.21875

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.length
old: 290.0
new: 21.0

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.N2
old: 118.0
new: 8.0

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.purity_ratio
old: 2.3266714172131917
new: 2.0786421168763445

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.time
old: 1026.6279591926702
new: 20.836749843245432

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.vocabulary
old: 109.0
new: 15.0

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.effort
old: 18479.303265468065
new: 375.06149717841777

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.n2
old: 94.0
new: 7.0

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.n1
old: 15.0
new: 8.0

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.N1
old: 172.0
new: 13.0

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.estimated_program_length
old: 674.7347109918256
new: 43.65148445440323

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.volume
old: 1962.7734541853083
new: 82.0447025077789

path: .spaces[0].spaces[0].spaces[3].metrics.halstead.difficulty
old: 9.414893617021276
new: 4.571428571428571

path: .spaces[0].spaces[0].spaces[3].metrics.nom.total
old: 4.0
new: 1.0

path: .spaces[0].spaces[0].spaces[3].metrics.nom.functions
old: 4.0
new: 1.0

path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_sei
old: 22.094168338054473
new: 105.30664094829032

path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_original
old: 61.141017217697765
new: 125.39425724332408

path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_visual_studio
old: 35.75498082906302
new: 73.32997499609597

path: .spaces[0].spaces[0].spaces[3].metrics.nexits.average
old: 1.0
new: 0.0

path: .spaces[0].spaces[0].spaces[3].metrics.nexits.sum
old: 4.0
new: 0.0

Code

void LSPAnnotate() {
  nsCOMPtr runnable(new LSPAnnotationGatherer());
  NS_DispatchBackgroundTask(runnable.forget());
}

Minimal test - lines (24, 135)

path: .spaces[0].metrics.cognitive.average
old: 0.0
new: 3.4

path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 17.0

path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 2.5

path: .spaces[0].metrics.cyclomatic.sum
old: 10.0
new: 20.0

path: .spaces[0].metrics.nexits.average
old: 1.0
new: 0.6

path: .spaces[0].metrics.nexits.sum
old: 4.0
new: 3.0

path: .spaces[0].metrics.mi.mi_sei
old: 26.026224866057124
new: 16.344650252062724

path: .spaces[0].metrics.mi.mi_original
old: 57.088350658970384
new: 47.65412074282419

path: .spaces[0].metrics.mi.mi_visual_studio
old: 33.3850003853628
new: 27.867906867148648

path: .spaces[0].metrics.nom.total
old: 4.0
new: 5.0

path: .spaces[0].metrics.nom.functions
old: 4.0
new: 5.0

path: .spaces[0].metrics.loc.blank
old: 26.0
new: 14.0

path: .spaces[0].metrics.loc.sloc
old: 85.0
new: 112.0

path: .spaces[0].metrics.loc.cloc
old: 5.0
new: 9.0

path: .spaces[0].metrics.loc.ploc
old: 54.0
new: 89.0

path: .spaces[0].metrics.loc.lloc
old: 4.0
new: 39.0

path: .spaces[0].metrics.halstead.time
old: 1091.7953933154513
new: 6595.253022224758

path: .spaces[0].metrics.halstead.n1
old: 15.0
new: 29.0

path: .spaces[0].metrics.halstead.volume
old: 2045.119175771382
new: 3414.571265632952

path: .spaces[0].metrics.halstead.purity_ratio
old: 2.2948829202769394
new: 1.4271859784683738

path: .spaces[0].metrics.halstead.n2
old: 96.0
new: 88.0

path: .spaces[0].metrics.halstead.estimated_program_length
old: 690.7597590033588
new: 709.3114312987818

path: .spaces[0].metrics.halstead.vocabulary
old: 111.0
new: 117.0

path: .spaces[0].metrics.halstead.length
old: 301.0
new: 497.0

path: .spaces[0].metrics.halstead.N1
old: 178.0
new: 286.0

path: .spaces[0].metrics.halstead.bugs
old: 0.24274740002018128
new: 0.8051585141730178

path: .spaces[0].metrics.halstead.difficulty
old: 9.609375
new: 34.76704545454545

path: .spaces[0].metrics.halstead.N2
old: 123.0
new: 211.0

path: .spaces[0].metrics.halstead.level
old: 0.1040650406504065
new: 0.028762869749959143

path: .spaces[0].metrics.halstead.effort
old: 19652.317079678123
new: 118714.55440004564

Code

namespace mozilla {
namespace crashreporter {

class LSPAnnotationGatherer : public Runnable {
  ~LSPAnnotationGatherer() {}

 public:
  LSPAnnotationGatherer() : Runnable("crashreporter::LSPAnnotationGatherer") {}
  NS_DECL_NSIRUNNABLE

  void Annotate();
  nsCString mString;
};

void LSPAnnotationGatherer::Annotate() {
  nsCOMPtr cr =
      do_GetService("@mozilla.org/toolkit/crash-reporter;1");
  bool enabled;
  if (cr && NS_SUCCEEDED(cr->GetEnabled(&enabled)) && enabled) {
    cr->AnnotateCrashReport("Winsock_LSP"_ns, mString);
  }
}

NS_IMETHODIMP
LSPAnnotationGatherer::Run() {
  DWORD size = 0;
  int err;
  // Get the size of the buffer we need
  if (SOCKET_ERROR != WSCEnumProtocols(nullptr, nullptr, &size, &err) ||
      err != WSAENOBUFS) {
    // Er, what?
    MOZ_ASSERT_UNREACHABLE(
        "WSCEnumProtocols succeeded when it should have "
        "failed");
    return NS_ERROR_FAILURE;
  }

  auto byteArray = MakeUnique(size);
  WSAPROTOCOL_INFOW* providers =
      reinterpret_cast(byteArray.get());

  int n = WSCEnumProtocols(nullptr, providers, &size, &err);
  if (n == SOCKET_ERROR) {
    // Lame. We provided the right size buffer; we'll just give up now.
    NS_WARNING("Could not get LSP list");
    return NS_ERROR_FAILURE;
  }

  nsCString str;
  for (int i = 0; i < n; i++) {
    AppendUTF16toUTF8(nsDependentString(providers[i].szProtocol), str);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iVersion);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iAddressFamily);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iSocketType);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iProtocol);
    str.AppendLiteral(" : ");
    str.AppendPrintf("0x%x", providers[i].dwServiceFlags1);
    str.AppendLiteral(" : ");
    str.AppendPrintf("0x%x", providers[i].dwProviderFlags);
    str.AppendLiteral(" : ");

    wchar_t path[MAX_PATH];
    int pathLen = MAX_PATH;
    if (!WSCGetProviderPath(&providers[i].ProviderId, path, &pathLen, &err)) {
      AppendUTF16toUTF8(nsDependentString(path), str);
    }

    str.AppendLiteral(" : ");
    // Call WSCGetProviderInfo to obtain the category flags for this provider.
    // When present, these flags inform Windows as to which order to chain the
    // providers.
    DWORD categoryInfo;
    size_t categoryInfoSize = sizeof(categoryInfo);
    if (!WSCGetProviderInfo(&providers[i].ProviderId, ProviderInfoLspCategories,
                            (PBYTE)&categoryInfo, &categoryInfoSize, 0, &err)) {
      str.AppendPrintf("0x%lx", categoryInfo);
    }

    str.AppendLiteral(" : ");
    if (providers[i].ProtocolChain.ChainLen <= BASE_PROTOCOL) {
      // If we're dealing with a catalog entry that identifies an individual
      // base or layer provider, log its provider GUID.
      RPC_CSTR provIdStr = nullptr;
      if (UuidToStringA(&providers[i].ProviderId, &provIdStr) == RPC_S_OK) {
        str.Append(reinterpret_cast(provIdStr));
        RpcStringFreeA(&provIdStr);
      }
    }

    if (i + 1 != n) {
      str.AppendLiteral(" \n ");
    }
  }

  mString = str;
  NS_DispatchToMainThread(
      NewRunnableMethod("crashreporter::LSPAnnotationGatherer::Annotate", this,
                        &LSPAnnotationGatherer::Annotate));
  return NS_OK;
}

void LSPAnnotate() {
  nsCOMPtr runnable(new LSPAnnotationGatherer());
  NS_DispatchBackgroundTask(runnable.forget());
}

}  // namespace crashreporter
}  // namespace mozilla

Minimal test - lines (38, 45)

path: .spaces[0].spaces[0].spaces[1].metrics.loc.sloc
old: 1.0
new: 8.0

path: .spaces[0].spaces[0].spaces[1].metrics.loc.lloc
old: 0.0
new: 2.0

path: .spaces[0].spaces[0].spaces[1].metrics.loc.ploc
old: 1.0
new: 8.0

path: .spaces[0].spaces[0].spaces[1].metrics.cyclomatic.sum
old: 1.0
new: 4.0

path: .spaces[0].spaces[0].spaces[1].metrics.cyclomatic.average
old: 1.0
new: 4.0

path: .spaces[0].spaces[0].spaces[1].metrics.nexits.average
old: null
new: 0.0

path: .spaces[0].spaces[0].spaces[1].metrics.cognitive.sum
old: 0.0
new: 2.0

path: .spaces[0].spaces[0].spaces[1].metrics.cognitive.average
old: null
new: 2.0

path: .spaces[0].spaces[0].spaces[1].metrics.nargs.average
old: null
new: 0.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.level
old: null
new: 0.1111111111111111

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.N2
old: 1.0
new: 18.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.time
old: 0.0
new: 98.70923408096291

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.vocabulary
old: 1.0
new: 26.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.difficulty
old: 0.0
new: 9.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.effort
old: 0.0
new: 1776.7662134573327

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.estimated_program_length
old: null
new: 96.2114326716684

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.n2
old: 1.0
new: 13.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.volume
old: 0.0
new: 197.41846816192583

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.n1
old: 0.0
new: 13.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.bugs
old: 0.0
new: 0.04889888278752872

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.purity_ratio
old: null
new: 2.2907483969444855

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.N1
old: 0.0
new: 24.0

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.length
old: 1.0
new: 42.0

path: .spaces[0].spaces[0].spaces[1].metrics.nom.functions
old: 0.0
new: 1.0

path: .spaces[0].spaces[0].spaces[1].metrics.nom.total
old: 0.0
new: 1.0

path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_original
old: null
new: 108.90935349047932

path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_sei
old: null
new: 81.82941163274273

path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_visual_studio
old: null
new: 63.68968040378908

Code

void LSPAnnotationGatherer::Annotate() {
  nsCOMPtr cr =
      do_GetService("@mozilla.org/toolkit/crash-reporter;1");
  bool enabled;
  if (cr && NS_SUCCEEDED(cr->GetEnabled(&enabled)) && enabled) {
    cr->AnnotateCrashReport("Winsock_LSP"_ns, mString);
  }
}

Minimal test - lines (25, 134)

path: .spaces[0].spaces[0].metrics.loc.ploc
old: 52.0
new: 87.0

path: .spaces[0].spaces[0].metrics.loc.lloc
old: 4.0
new: 39.0

path: .spaces[0].spaces[0].metrics.loc.blank
old: 27.0
new: 15.0

path: .spaces[0].spaces[0].metrics.loc.sloc
old: 83.0
new: 110.0

path: .spaces[0].spaces[0].metrics.loc.cloc
old: 4.0
new: 8.0

path: .spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 682.7396417255678
new: 701.417532997539

path: .spaces[0].spaces[0].metrics.halstead.n1
old: 15.0
new: 29.0

path: .spaces[0].spaces[0].metrics.halstead.level
old: 0.10382513661202186
new: 0.02857142857142857

path: .spaces[0].spaces[0].metrics.halstead.n2
old: 95.0
new: 87.0

path: .spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 2.28341017299521
new: 1.4170051171667453

path: .spaces[0].spaces[0].metrics.halstead.time
old: 1084.9580685524234
new: 6600.806707810288

path: .spaces[0].spaces[0].metrics.halstead.N1
old: 177.0
new: 285.0

path: .spaces[0].spaces[0].metrics.halstead.bugs
old: 0.24173287537922108
new: 0.8056104523458466

path: .spaces[0].spaces[0].metrics.halstead.volume
old: 2027.6265543438733
new: 3394.700592588148

path: .spaces[0].spaces[0].metrics.halstead.effort
old: 19529.24523394362
new: 118814.52074058518

path: .spaces[0].spaces[0].metrics.halstead.N2
old: 122.0
new: 210.0

path: .spaces[0].spaces[0].metrics.halstead.length
old: 299.0
new: 495.0

path: .spaces[0].spaces[0].metrics.halstead.vocabulary
old: 110.0
new: 116.0

path: .spaces[0].spaces[0].metrics.halstead.difficulty
old: 9.63157894736842
new: 35.0

path: .spaces[0].spaces[0].metrics.cognitive.average
old: 0.0
new: 3.4

path: .spaces[0].spaces[0].metrics.cognitive.sum
old: 0.0
new: 17.0

path: .spaces[0].spaces[0].metrics.cyclomatic.sum
old: 9.0
new: 19.0

path: .spaces[0].spaces[0].metrics.cyclomatic.average
old: 1.0
new: 2.7142857142857144

path: .spaces[0].spaces[0].metrics.nom.functions
old: 4.0
new: 5.0

path: .spaces[0].spaces[0].metrics.nom.total
old: 4.0
new: 5.0

path: .spaces[0].spaces[0].metrics.nexits.sum
old: 4.0
new: 3.0

path: .spaces[0].spaces[0].metrics.nexits.average
old: 1.0
new: 0.6

path: .spaces[0].spaces[0].metrics.mi.mi_sei
old: 25.20806162393945
new: 16.06772673638477

path: .spaces[0].spaces[0].metrics.mi.mi_original
old: 57.74875189833699
new: 48.206369678040815

path: .spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 33.77119994054795
new: 28.190859460842585

Code

namespace crashreporter {

class LSPAnnotationGatherer : public Runnable {
  ~LSPAnnotationGatherer() {}

 public:
  LSPAnnotationGatherer() : Runnable("crashreporter::LSPAnnotationGatherer") {}
  NS_DECL_NSIRUNNABLE

  void Annotate();
  nsCString mString;
};

void LSPAnnotationGatherer::Annotate() {
  nsCOMPtr cr =
      do_GetService("@mozilla.org/toolkit/crash-reporter;1");
  bool enabled;
  if (cr && NS_SUCCEEDED(cr->GetEnabled(&enabled)) && enabled) {
    cr->AnnotateCrashReport("Winsock_LSP"_ns, mString);
  }
}

NS_IMETHODIMP
LSPAnnotationGatherer::Run() {
  DWORD size = 0;
  int err;
  // Get the size of the buffer we need
  if (SOCKET_ERROR != WSCEnumProtocols(nullptr, nullptr, &size, &err) ||
      err != WSAENOBUFS) {
    // Er, what?
    MOZ_ASSERT_UNREACHABLE(
        "WSCEnumProtocols succeeded when it should have "
        "failed");
    return NS_ERROR_FAILURE;
  }

  auto byteArray = MakeUnique(size);
  WSAPROTOCOL_INFOW* providers =
      reinterpret_cast(byteArray.get());

  int n = WSCEnumProtocols(nullptr, providers, &size, &err);
  if (n == SOCKET_ERROR) {
    // Lame. We provided the right size buffer; we'll just give up now.
    NS_WARNING("Could not get LSP list");
    return NS_ERROR_FAILURE;
  }

  nsCString str;
  for (int i = 0; i < n; i++) {
    AppendUTF16toUTF8(nsDependentString(providers[i].szProtocol), str);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iVersion);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iAddressFamily);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iSocketType);
    str.AppendLiteral(" : ");
    str.AppendInt(providers[i].iProtocol);
    str.AppendLiteral(" : ");
    str.AppendPrintf("0x%x", providers[i].dwServiceFlags1);
    str.AppendLiteral(" : ");
    str.AppendPrintf("0x%x", providers[i].dwProviderFlags);
    str.AppendLiteral(" : ");

    wchar_t path[MAX_PATH];
    int pathLen = MAX_PATH;
    if (!WSCGetProviderPath(&providers[i].ProviderId, path, &pathLen, &err)) {
      AppendUTF16toUTF8(nsDependentString(path), str);
    }

    str.AppendLiteral(" : ");
    // Call WSCGetProviderInfo to obtain the category flags for this provider.
    // When present, these flags inform Windows as to which order to chain the
    // providers.
    DWORD categoryInfo;
    size_t categoryInfoSize = sizeof(categoryInfo);
    if (!WSCGetProviderInfo(&providers[i].ProviderId, ProviderInfoLspCategories,
                            (PBYTE)&categoryInfo, &categoryInfoSize, 0, &err)) {
      str.AppendPrintf("0x%lx", categoryInfo);
    }

    str.AppendLiteral(" : ");
    if (providers[i].ProtocolChain.ChainLen <= BASE_PROTOCOL) {
      // If we're dealing with a catalog entry that identifies an individual
      // base or layer provider, log its provider GUID.
      RPC_CSTR provIdStr = nullptr;
      if (UuidToStringA(&providers[i].ProviderId, &provIdStr) == RPC_S_OK) {
        str.Append(reinterpret_cast(provIdStr));
        RpcStringFreeA(&provIdStr);
      }
    }

    if (i + 1 != n) {
      str.AppendLiteral(" \n ");
    }
  }

  mString = str;
  NS_DispatchToMainThread(
      NewRunnableMethod("crashreporter::LSPAnnotationGatherer::Annotate", this,
                        &LSPAnnotationGatherer::Annotate));
  return NS_OK;
}

void LSPAnnotate() {
  nsCOMPtr runnable(new LSPAnnotationGatherer());
  NS_DispatchBackgroundTask(runnable.forget());
}

}  // namespace crashreporter