In this section:

Introduction

The asminfer tool applies additional inference modules to the static data file (.pail) that has been merged with dynamic data. An inference module provides additional analysis of the coverage information.

In this section, we assume that you've already installed Parasoft ASMTools and that they are on your system path. Refer to Parasoft ASMTools for information about the full tool chain, including installation and requirements. 

Basic Usage

Run asminfer and specify the static data file and inference module you want to apply:

$ asminfer --input-file /path/to/static-data-file.pail --inference-module <module>

Use the --input-file flag ( or -i) to specify the static data file. This file is created by instrumenting  objects, archives, and executables using the Asminst and merged with a dynamic data file (.padd) with the Asmcovbuf to output coverage.  

Use the --inference-module flag (or -m) to specify the name of the inference module you want to apply. This flag is optional. If not included or if a module name is not specified, all available modules will be be invoked.

You can run asminfer multiple times on the same .pail file.

Examples

Windows
$ asminfer --input-file C:\path\to\static\data\example.pail --inference-module switch_tracking
Unix
$ asminfer --input-file /path/to/static/data/example.pail --inference-module switch_tracking

Options

--blacklist <path-to-file>

-b <path-to-file>

--excluded-function-file <path-to-file>

Specifies a file that contains a list of functions to be excluded from instrumentation in the current translation unit.

You can use this option multiple times to specify several lists. 

--help

-h

Prints the descriptions of the options for asminfer

--inference-module=<module name>

-m

Specifies the name of the inference module to be applied to the specified static data file

--input-file=<path/to/static/data/file.pail>

-i

Specifies the static data to be processed by the specified inference module

--list-modules

-l

Prints available inference modules. 

--output-file <path-and-name>

-o <path-and-name>

Specifies the name/location of the output file. 

--version

-v

Print out the version header of the too.l

--whitelist <path-to-file>

-w <path-to-file>

--include-function-file <path-to-file>

Specifies a file that contains a list of functions to be included for instrumentation in the current translation unit.

You can use this option multiple times to specify several lists. 

Known Issues

Switch tracking omits switch cases that have been removed by the compiler during optimization.

Some compiler optimizations, such as -Ospace/-Osize from the ppc_ghs_2017_1 compiler, remove cases from a switch to save space. This change is reflected in the interleaved output of the compiler by not associating the case with any assembly code.

Since the compiler has optimized the case away, there is no way to identify that the case was taken or not taken. It will not show up in the switch statistics because of this.

The following C example demonstrates the issue:

int foo(int a)
{
  switch(a)
  {
    case 1:
      a++;
      break;
    case 2:
      a--;
      break;
    case 3:
      a = 0;
      break;
    case 4:
      a += 2;
      break;
    case 5:
      a -= 2;
      break;
    case 6:
      a = 1000;
      break;
    case 7:
      a = 50;
      break;
    case 8:
      a = a * a;
      break;
    default:
      a += a;
  }
  return a;
}

The following output shows the results with interleaving when using the -Ospace /-Osize optimization for the ppc_ghs_2017_1 compiler:

#Version:       C-POWERPC 2017.1.4 RELEASE VERSION
#Release:       Compiler v2017.1.4
#Revision Date: Sun Apr 9 19:41:34 2017
#Release Date:  Sun Apr 9 17:00:05 2017
	.text
	.align	2
	.global	simpleSwitch7_50
simpleSwitch7_50:
#1: int simpleSwitch7_50(int a)
#2: {
#3:   switch(a)
	addi	r12, r3, -2
	cmplwi	r12, 6
	bgt	.L13
	slwi	r12, r12, 1
	addis	r12, r12, %hiadj(.L95)
	lhzu	r11, %lo(.L95)(r12)
	add	r12, r12, r11
	mtctr	r12
	bctr
.L95:
	.short	.L6-.L95-0
	.short	.L7-.L95-2
	.short	.L8-.L95-4
	.short	.L9-.L95-6
	.short	.L10-.L95-8
	.short	.L11-.L95-10
	.short	.L12-.L95-12
	.short	0-0-0
.L6:
#4:   {
#5:     case 1:
#6:       a++;
#7:       break;
#8:     case 2:
#9:       a--;
	subi	r3, r3, 1
	blr
#10:       break;
#11:     case 3:
.L7:
#12:       a = 0;
	li	r3, 0
	blr
#13:       break;
#14:     case 4:
.L8:
#15:       a += 2;
	addi	r3, r3, 2
	blr
#16:       break;
#17:     case 5:
.L9:
#18:       a -= 2;
	subi	r3, r3, 2
	blr
#19:       break;
#20:     case 6:
.L10:
#21:       a = 1000;
	li	r3, 1000
	blr
#22:       break;
#23:     case 7:
.L11:
#24:       a = 50;
	li	r3, 50
	blr
#25:       break;
#26:     case 8:
.L12:
#27:       a = a * a;
	mullw	r3, r3, r3
	blr
#28:       break;
#29:     default:
.L13:
#30:       a += a;
	slwi	r3, r3, 1
#31:   }
#32:   return a;
	blr
	.type	simpleSwitch7_50,@function
	.size	simpleSwitch7_50,$-simpleSwitch7_50
	.align	2
#33: }

The assembly performs a subtraction in lines 30-38. This is because case 1, which performs addition, has been optimized out. The compiler has determined that a+=a in the default case yields the same behavior as a++ when a == 1. Thus, when a == 1, the default case is taken because they are equivalent. This is a function of the compiler, not asminfer.

There is no generated code available for case 1, so it cannot have independent coverage because it can no longer be distinguished from the default case in this scenario.

Because the compiler optmized out case 1, there is no code associated with case 1. Asminfer will correctly ignore case 1 because there is no actual code associated with it. This is expected known behavior with asminfer.

If case 1 contained more code, e.g., if source coverage was applied, then the compiler would have deemed the case to be different from the default and thus would not have been optimized out. The following table describes the behavior:

#3:    switch(a)
--->	----------------------------------------------------------

	Switch statement overview:
	----------------------------------------------------------
	Name:     Code was:       Branch was:     ASM equivalent:
	default:  Covered         Taken           Label: .L13
	case 2:   Covered         Taken           Label: .L6
	case 3:   Covered         Taken           Label: .L7
	case 4:   Covered         Taken           Label: .L8
	case 5:   Not Covered     Not Taken       Label: .L9
	case 6:   Not Covered     Not Taken       Label: .L10
	case 7:   Covered         Taken           Label: .L11
	case 8:   Not Covered     Not Taken       Label: .L12
	----------------------------------------------------------

The compiler was able to save space by optimizing out paths of execution. The tradeoff, however, was that tracking the code much more difficult. The only way to actually verify the results with this level of optimization enabled is to manually analyze the assembly code line by line to determine the code's function.

When using other optimization styles. such as -Ospeed , the compiler is free to optimize cases away, as well. Asminfer will report the data as it sees it.

  • No labels