OpenCover not finding PDBs on the build server - unit-testing

I have the following command on my local machine:
C:\Tools\opencover\OpenCover.Console.exe
-register
-target:C:\local-source\develop\Lib\NuGetPackages\xunit.runner.console.2.4.0\tools\net462\xunit.console.exe
-targetargs:"C:\local-source\Develop\Src\LN.B.Tests.Integration\bin\Release\LN.B.Tests.Integration.dll -noshadow"
-output:TestCoverage.xml
-log:Verbose
"-filter:+[*]* -[*xunit*]* -[*RefEmit_InMemoryManifestModule*]* -[*AutoFixture*]*"
The command displays the following output, which is expected:
Visited Classes 1103 of 5472 (20.16)
Visited Methods 9832 of 65663 (14.97)
Visited Points 25472 of 318612 (7.99)
Visited Branches 13949 of 209530 (6.66)
==== Alternative Results (includes all methods including those without corresponding source) ====
Alternative Visited Classes 1324 of 6608 (20.04)
Alternative Visited Methods 10689 of 73849 (14.47)
Now, I want to run the same command on a Build server targeting a dll that is generated by a daily build:
C:\Tools\opencover\OpenCover.Console.exe
-register
-target:D:\Build\XG5\BuildDeployDev1\Lib\NuGetPackages\xunit.runner.console.2.4.0\tools\net462\xunit.console.exe
-targetargs:"Src\LN.B.Tests.Integration\bin\Release\LN.B.Tests.Integration.dll -noshadow"
-output:TestCoverage.xml
-log:Verbose
"-filter:+[*]* -[*xunit*]* -[*RefEmit_InMemoryManifestModule*]* -[*AutoFixture*]*"
For some reason, the output is different, and I can't wrap my head around why:
Visited Classes 61 of 405 (15.06)
Visited Methods 591 of 4729 (12.5)
Visited Points 3295 of 26321 (12.52)
Visited Branches 2017 of 16924 (11.92)
==== Alternative Results (includes all methods including those without corresponding source) ====
Alternative Visited Classes 67 of 458 (14.63)
Alternative Visited Methods 635 of 5341 (11.89)
Looking at the log file, I get a lot of Cannot instrument D:\Jenkins\workspace\XG5_OpenCover2.2\Src\LN.B.Tests.Integration\bin\Release\LN.Common.Repository.dll as no PDB/MDB could be loaded and the output lists my dlls as: MissingPDB
My user has admin privileges on both machines is admin
Opencover version: 4.6.519.0 (Same behavior with the newer version)
I verified that the built pdbs are "PDB only"
I have tried -register:user, -register:Path32, and -register:Path64
I have tried running regsvr32 "C:\Tools\opencover\x64\OpenCover.Profiler.dll" and "C:\Tools\opencover\x32\OpenCover.Profiler.dll"
I have reviewed: https://github.com/opencover/opencover/blob/master/main/OpenCover.Documentation/Usage.pdf
What else can I try to fix this issue? I think I've exhausted all the options.

Related

sbt test:compile does not compile all tests

I'm trying to run a single test class ThisIsTheClassTest.java in a Java Play project but fails and cannot seem to find the cause.
When I run test:compile the response is plain [success] Total time: 1 s, completed Jun 5, 2018 9:30:19 PM
But when using autocomplete to list all available test classes there is one missing.
It seems that it might be the filename itself (for whatever reason) as it all works well if I copy the entire code into another file ThisIsNotTheFile.java and run test:Compile. But even if I delete the entire file ThisIsTheClassTest.java and add it again it does not work.
If one of the classes did not compile I would not expect the answer [success].
Is there a way to see skipped/failed/ignored compilations or at least additional logging?
The code is probably in the wrong directory.

How to properly debug a binary generated by `go test -c` using GDB?

The go test command has support for the -c flag, described as follows:
-c Compile the test binary to pkg.test but do not run it.
(Where pkg is the last element of the package's import path.)
As far as I understand, generating a binary like this is the way to run it interactively using GDB. However, since the test binary is created by combining the source and test files temporarily in some /tmp/ directory, this is what happens when I run list in gdb:
Loading Go Runtime support.
(gdb) list
42 github.com/<username>/<project>/_test/_testmain.go: No such file or directory.
This means I cannot happily inspect the Go source code in GDB like I'm used to. I know it is possible to force the temporary directory to stay by passing the -work flag to the go test command, but then it is still a huge hassle since the binary is not created in that directory and such. I was wondering if anyone found a clean solution to this problem.
Go 1.5 has been released, and there is still no officially sanctioned Go debugger. I haven't had much success using GDB for effectively debugging Go programs or test binaries. However, I have had success using Delve, a non-official debugger that is still undergoing development: https://github.com/derekparker/delve
To run your test code in the debugger, simply install delve:
go get -u github.com/derekparker/delve/cmd/dlv
... and then start the tests in the debugger from within your workspace:
dlv test
From the debugger prompt, you can single-step, set breakpoints, etc.
Give it a whirl!
Unfortunately, this appears to be a known issue that's not going to be fixed. See this discussion:
https://groups.google.com/forum/#!topic/golang-nuts/nIA09gp3eNU
I've seen two solutions to this problem.
1) create a .gdbinit file with a set substitute-path command to
redirect gdb to the actual location of the source. This file could be
generated by the go tool but you'd risk overwriting someone's custom
.gdbinit file and would tie the go tool to gdb which seems like a bad
idea.
2) Replace the source file paths in the executable (which are pointing
to /tmp/...) with the location they reside on disk. This is
straightforward if the real path is shorter then the /tmp/... path.
This would likely require additional support from the compiler /
linker to make this solution more generic.
It spawned this issue on the Go Google Code issue tracker, to which the decision ended up being:
https://code.google.com/p/go/issues/detail?id=2881
This is annoying, but it is the least of many annoying possibilities.
As a rule, the go tool should not be scribbling in the source
directories, which might not even be writable, and it shouldn't be
leaving files elsewhere after it exits. There is next to nothing
interesting in _testmain.go. People testing with gdb can break on
testing.Main instead.
Russ
Status: Unfortunate
So, in short, it sucks, and while you can work around it and GDB a test executable, the development team is unlikely to make it as easy as it could be for you.
I'm still new to the golang game but for what it's worth basic debugging seems to work.
The list command you're trying to work can be used so long as you're already at a breakpoint somewhere in your code. For example:
(gdb) b aws.go:54
Breakpoint 1 at 0x61841: file /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.go, line 54.
(gdb) r
Starting program: /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.test
[snip: some arnings about BinaryCache]
Breakpoint 1, github.com/stellar/deliverator/aws.imageIsNewer (latest=0xc2081fe2d0, ami=0xc2081fe3c0, ~r2=false)
at /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.go:54
54 layout := "2006-01-02T15:04:05.000Z"
(gdb) list
49 func imageIsNewer(latest *ec2.Image, ami *ec2.Image) bool {
50 if latest == nil {
51 return true
52 }
53
54 layout := "2006-01-02T15:04:05.000Z"
55
56 amiCreationTime, amiErr := time.Parse(layout, *ami.CreationDate)
57 if amiErr != nil {
58 panic(amiErr)
This is just after running the following in the aws subdir of my project:
go test -c
gdb aws.test
As an additional caveat, it does seem very selective about where breakpoints can be placed. Seems like it has to be an expression but that conclusion is only via experimentation.
If you're willing to use tools besides GDB, check out godebug. To use it, first install with:
go get github.com/mailgun/godebug
Next, insert a breakpoint somewhere by adding the following statement to your code:
_ = "breakpoint"
Now run your tests with the godebug test command.
godebug test
It supports many of the parameters from the go test command.
-test.bench string
regular expression per path component to select benchmarks to run
-test.benchmem
print memory allocations for benchmarks
-test.benchtime duration
approximate run time for each benchmark (default 1s)
-test.blockprofile string
write a goroutine blocking profile to the named file after execution
-test.blockprofilerate int
if >= 0, calls runtime.SetBlockProfileRate() (default 1)
-test.count n
run tests and benchmarks n times (default 1)
-test.coverprofile string
write a coverage profile to the named file after execution
-test.cpu string
comma-separated list of number of CPUs to use for each test
-test.cpuprofile string
write a cpu profile to the named file during execution
-test.memprofile string
write a memory profile to the named file after execution
-test.memprofilerate int
if >=0, sets runtime.MemProfileRate
-test.outputdir string
directory in which to write profiles
-test.parallel int
maximum test parallelism (default 4)
-test.run string
regular expression to select tests and examples to run
-test.short
run smaller test suite to save time
-test.timeout duration
if positive, sets an aggregate time limit for all tests
-test.trace string
write an execution trace to the named file after execution
-test.v
verbose: print additional output

Moved Model Glue App No Longer Working

A model glue site we use had to be moved to another physically different location. I updated all the paths in ModelGlue.xml, ColdSpring.xml and other specific files, but I keep getting the following error. Note: the current physical path is jmc.divisions.medical_oncology.admin.controller.Controller
Could not find the ColdFusion Component or Interface jmc.medical_oncology.admin.controller.Controller.
Ensure that the name is correct and that the component or interface exists.
The error occurred in E:\Inetpub\framework\ModelGlue\unity\loader\XmlConfigurationLoader.cfc: line 234
Called from E:\Inetpub\framework\ModelGlue\unity\loader\XmlConfigurationLoader.cfc: line 83
Called from E:\Inetpub\framework\ModelGlue\unity\loader\FrameworkLoader.cfc: line 98
Called from E:\Inetpub\framework\ModelGlue\unity\ModelGlue.cfm: line 116
Nevermind! Apparently, the system held onto some app-level caching for almost 48 hours. It finally works now.

What is a good way to create a string for crash reporting Win32 C++ that reflects the cause of the crash?

We're using Fogbugz for tracking issues and I am in the middle of writing a C++ wrapper around the XML API for Fogbugz.
The best practice seems to be to use the "scout" field so that similar/same crashes are just counted but not reported again. To do that we need a unique string for a particular cause of a crash.
In Win32 - after getting a dmp file or other crash handler what is a good way to make a unique string for a crash? (we're going to create a dmp file and send it to the fogbugz server)
In previous postings/articles/etc Joel has made various suggestions but much of those counted on a language like C# that use reflection and have a lot of information that is either harder to get or not possible to get.
Have any other people gotten things like stack traces or other things to make scout entries in fogbugz?
EDIT
To clarify - we don;t want a unique id for every incident - there are likely crashes that have the same code path. We want to capture that. I was thinking that we would get the last few stack calls that are in our code (not ones from win32 DLLs) - but not sure how to go about doing this.
Reporting every crash as unique is not right. Reporting all crashes under the same case is not right. Different users repeating a scenario that causes a crash should map to the same incident.
EDIT
What I think we want is a general "signature" of a crash - based on what is on the stack. Similar stacks should have the same signature. For example - take the top 5 methods that are in our app and then the first call (if any) we make into an MS DLL. This would probably be sufficient for a signature and would likely correlate the crashes that are "the same".
So how does one get the list of methods on the stack? And how can you tell if they are from your own app or in another DLL?
EDIT - NOTE
We want to create a "bucket id"/signature while in the exception handler so that we can create the minidump and send it to fogbugz as a scout description. Alternatively we can load up the dump on t he next start of the app and send it then with a signature we generate.
Here in my project I use the Address Memory of the Crash as a "Unique" ID.
IMO the best thing you can use will be bucket id from dump analysis. Use properly configured Debugging Tools for Windows (windbg), one can do !analyze -v and classify your dumps into different buckets based on bucket id. Bucket id guaranteed that if two dumps are the same, their bucket id will be the same. That solves part of the puzzle.
Many times two dumps rooted from same problem will create different bucket id's (maybe version difference, say your 1.0 and 1.1 both crash at same point). You can use faulting module and stack signature to correlate bugs from the same point of fault.
There will be certain things that causes very random dumps (e.g. heap corruption, the faulting module is typically the victim). Therefore dump analysis should be considered best-effort. When you can't, you can't.
I used something like this to generate exceptions in my last app (MSVC), so every error would get logged with the sourcefile and line it occured on:
class Error {
//...
public: Error(string file, string line, string error) ;
};
#define ERROR(err) Error(__FILE__, __LINE__, err)
It's probably a little bit late, but I will add my solution here, too, in case it can help other people.
You can do this using fools from "Debugging Tools for Windows", for example windbg.exe or better kd.exe.
Running the command "kd.exe -z "path_to_dump.dmp" -c "kd;q" >> dumpstack.txt, you might get the following result:
Microsoft (R) Windows Debugger Version 10.0.15063.400 X86
Copyright (c) Microsoft Corporation. All rights reserved.
Loading Dump File [d:\work\bugs\14122\myexe.exe.2624.dmp]
User Mini Dump File with Full Memory: Only application data is available
************* Symbol Path validation summary **************
Response Time (ms) Location
Deferred srv*C:\Symbols*http://msdl.microsoft.com/download/symbols
Symbol search path is: srv*C:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows 10 Version 15063 MP (4 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS
15063.0.x86fre.rs2_release.170317-1834
Machine Name:
Debug session time: Fri Oct 13 00:09:01.000 2017 (UTC + 1:00)
System Uptime: 0 days 0:18:33.797
Process Uptime: 0 days 0:03:40.000
................................................................
.....................................................
Loading unloaded module list
..............................
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(a40.2580): Security check failure or stack buffer overrun - code c0000409 (first/second chance not available)
eax=00000001 ebx=00000000 ecx=00000007 edx=77cc4350 esi=00000000 edi=00000000
eip=62ae7666 esp=0b75e17c ebp=0b75e1a8 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
msvcr120!abort+0x28:
62ae7666 cd29 int 29h
0:068> kd: Reading initial command 'kb;q'
ChildEBP RetAddr Args to Child
0b75e178 62addc5f 935dda1f 00000000 00000000 msvcr120!abort+0x28
0b75e1a8 0b75e7d4 62a9b436 0b75e1dc 62a52aa5 msvcr120!terminate+0x33
WARNING: Frame IP not in any known module. Following frames may be wrong.
0b75e1ac 62a9b436 0b75e1dc 62a52aa5 00000000 0xb75e7d4
0b75e1b4 62a52aa5 00000000 62a59740 0b75e7d4 msvcr120!__FrameUnwindToState+0x89
0b75e1c8 62a52b33 00000000 00000000 00000000 msvcr120!_EH4_CallFilterFunc+0x12
0b75e1f4 62a5a0f3 62b1f7b8 62a4f7c6 0b75e324 msvcr120!_except_handler4_common+0x8e
0b75e214 77cd6152 0b75e324 0b75e7c4 0b75e344 msvcr120!_except_handler4+0x1e
0b75e238 77cd6124 0b75e324 0b75e7c4 0b75e344 ntdll!ExecuteHandler2+0x26
0b75e30c 77cc4266 0b75e324 0b75e344 0b75e324 ntdll!ExecuteHandler+0x24
0b75e30c 74cf28f2 0b75e324 0b75e344 0b75e324 ntdll!KiUserExceptionDispatcher+0x26
0b75e684 62a59339 e06d7363 00000001 00000003 KERNELBASE!RaiseException+0x62
0b75e6c4 6001821c 0b75e6e4 6004e1bc 946a8f2a msvcr120!_CxxThrowException+0x5b
0b75e6f8 60018042 0b75e720 946a8efa ffffffff mymodule!FunctionC+0x7c
0b75e730 60016544 946a8ece ffffffff 092889d8 mymodule!FunctionB+0x32
0b75e754 600166b8 00842338 6000588d 00000001 myothermodule!FunctionB+0x44
From this stack, you can create a unique bucket if you take for example only your methods from the stack and concatenate them in a string: "mymodule!FunctionC+0x7c;mymodule!FunctionB+0x32;myothermodule!FunctionB+0x44". In order for this to work, you need to have access to you personal symbols server, either using the environment variable _NT_SYMBOL_PATH or with the -y command line switch.
You can alternatively create a string from the return addresses only (second column): "62addc5f,0b75e7d4,62a9b436,62a52aa5,62a52b33,62a5a0f3,77cd6152,77cd6124,77cc4266,74cf28f2,62a59339,6001821c,60018042,60016544,600166b8"
Just use an MD5 string generated from the dump file and you will likely to get a unique string for every crash.
I would start with collecting the data on how often every function in your code has been "flashed" in a crash report stack trace. Every report would have to be added to some kind of database, and every function would have to be indexed so that you could later query, which functions seem to crash more often than others. (And of course, functions like main() will be in every report, but that's understandable).
Or, you think that only crash reports seem to be the problem, you could just remove all those entries from crash stack traces, and then hash the rest (your functions). That way you could see if any particular call chain of your own functions causes a crash repeatedly, no matter what external functions have been called in between.
Then of course, some of the more complicated problems will not be captured this way anyway, as the stack trace will be completely different. To help that, you could record other data from your application along with the stack trace in every report, like sizes of buffers, counters, states of different parts of the application and so on... And then do some statistics on that.

Crystal Reports seems to have an 80 section per group limit

Crystal Reports seems to have an 80 section per group limit
Environment:
Microsoft Windows XP
Professional
Version 2002
Service Pack 3
Crystal Reports XI (Release 1)
Calling the Crystal Reports Engine crpe32.dll version 11.0.0.1445
Via Crystal VCL 11 libraries
Via Borland C++Builder 6 Enterprise Suite Version 6.0 (Build 10.166)
I found the report containing 86 sections (in one group)
ran just fine using the Crystal Reports XI exe found at
C:\Program Files\Business Objects\Crystal Reports 11\crw32.exe
However, when I called the same report from an executable compiled
using Borland C++Builder -> VCL calls -> crpe32.dll
IT DID NOT PRINT.
I spent many frustrating hours debugging the exe.
I used the divide and conquer debugging approach and devised
a state machine that would do the following while logging every
state along the way:
Load the Engine via LoadEngine;
Open the Engine via OpenEngine;
Open the PrintJob via OpenJob;
Close the PrintJob via CloseJob;
Close the Engine via CloseEngine;
Unload the Engine via UnloadEngine;
I found that the report errored out at OpenJob
with Crpe1->Status() status crsJobFailed
Crpe1->LastErrorNumber() was "505: No print destination specified"
Here's the play by play (I output this to a file):
LoadEngine() started
LoadEngine() completed. The handle to CRPE32.DLL is: 728956928
EngineOpen() started
EngineOpen() completed. Engine is already opened.
JobIsOpen() started.
JobIsOpen() completed. The PrintJob is open.
Execute() started
Status() crsJobFailed
Execute() failed.
Error state.
LastErrorNumber 505: No print destination specified.
C:\REPORTS\ProblemReport.rpt
Please first call PEOutputToWindow or PEOutputToPrinter!
Execute <PEStartPrintJob>
Finished state.
Back to the report:
Deleting some /*comment*/ sections from the report brought the number of
sections down to 78 and voila ... the report printed out just fine from the
executable compiled on Borland C++Builder -> VCL calls -> crpe32.dll
My conclusion:
Avoid creating over 80 sections in a group.
As a workaround, you can add another group having
the same GROUP BY column (essentially, repeat the
same group) and create all the extra sections needed
in the new group (the repeated group).
It's the equivalent of writing the following SQL
SELECT
column1
column1
FROM table
GROUP BY
column1,
column1;
Has anyone else had this problem?
If yes, what solution have you devised?