Skip to main content

Base Visual Studio debugging functionalities

Cred ca un programator intr-o zi normala de lucru, are nevoie cel putin odata pe zi sa faca debug la cod. Visual Studio are extrem de multe functionalitati care pot sa fie utile in procesul de debug. Din pacate, dupa o perioada de timp uitam de toate feature-urile pe care le avem la dispozitie. In acest post o sa incerc sa trec peste o parte din aceste feature. In prima parte a postului o sa folosesc Visual Studio 2010, iar Visual Studio 2012 o sa folosesc doar pentru cele specifice la Visual Studio 2012.
In mod normal pentru a putea face debug trebuie sa rulam proiectul nostru in dubug. Acest lucru se poate face folosind tasta F5 sau apasand butonul "Start Debugging" din meniul "Debug". In cazul in care procesul nostru deja ruleaza este nevoie sa ne atasam la proces. Acest lucru se face din meniu "Debug-> Attach to Process" sau prin combinatia de taste "Alt+Ctrl+P". 
Puteti sa va atasati la unul sau mai multe procese. In cazul in care nu gasiti procesul in lista, inseamna ca acesta ruleaza sub un alt user sau in alta sesiune. Pentru a putea vedea si acest procese este nevoie sa selectati checkbox-ul "Show processes from all users" sau "Show processes in all sessions". In cazul in care proiectul la care va atasati nu este 1 la 1 cu versiunea pe care o aveti deschisa s-ar putea ca sa nu puteti intra in toate brakepoint-urile pe care le adaugati. In cazul in care adaugati brakepoint-uri si observati ca dupa ce v-ati atasat la proces, acestea au un cerculet rosu si cu un semnul exclamarii langa ele, inseamna ca sursa si versiunea la aplicatie la care faceti debug nu este 1 la 1. Pentru a putea totusi sa faceti debug este nevoie sa debifati optiunea "Require source files to exactly match the original version" din "Tools->Options".
Aceiasi optiune, pentru a accepta ca codul din solutia deschisa sa fie diferit fata de cel care ruleaza poate sa fie gasit data dati click pe breakpoint si selectati optiunea "Location". In aceasta fereastra o sa puteti selecta locatia unde breakpoit-ul este adaugat.
Daca tot am inceput cu optiunile pe care le avem pe un breakpoint, o sa continui si cu restul. Urmatoarea optiune este de adaugare de conditii la breakpoint. Pe baza acestor conditii, putem seta daca aplicatia sa se opreasca la un breakpoint sau nu. Putem sa adaugam orice fel de conditie, iar vestea buna ca avem intelliSense in acest loc, a.i. ne este foarte usor sa definim una sau mai multe conditii legate prin &&, ||. Optiunea de "Has changes" este foarte utila cand vrem ca sa intram in breakpoint cand valoarea conditiei s-a schimbat. In acest caz valoare nu trebuie sa fie obligatoriu de tip boolean.
Urmatorul setup pe care il putem face la un breakpoint este sa setam un contor pentru hits counter. By default, la fiecare atingere a unui breakpoint cand conditia este sadifacuta, aplicatia o sa se opreasca la breakpoint. Dar sunt cazuri cand vrem sa specificam doar la primele 3 sa se opreasca sau cand aceasta valoare este mai mare decat 10.
In cazul in care vrem ca un breakpoint sa fie activ doar pe anumite thread-uri sau doar pe anumite procese (cazul in care suntem atasati la mai multe procese) putem sa ne folosim de urmatoarea optiune care apare in meniul unui breakpoint - "Filter". Putem sa setam ca un breakpoint sa intre doar pe un thread cu un anumit id sau nume sau doar daca ruleaza pe o anumita masina. In exemplul de mai jos, doar in cazul in threadul se numeste "CustomThread"  si rulam pe o masina cu numele "W8" breakpointul o sa fie activ.
Urmatorul lucru pe care il putem seta este un macro care sa se execute cand breakpointul este lovit sau sa afisam un anumit mesaj. Pana in momentul de fata nu am avut nevoie de aceasta functionalitate, dar ce mi se pare interesant la ea este ca putem seta ca executia codului sa se continue, dupa ce s-a executat actiunea custom din macro sau s-a afisat mesajul nostru, Un macro destul de interesant pe care l-am vazut in schimb era generarea automata a unui fisier de dump de fiecare data cand breakpointul era lovit.
Fiecarui breakpoint ii pot sa fie atasate unul sau mai multe label-uri. Acestea ne pot ajuta sa grupa breakpoint-urile in functie de anumite date. Pentru a putea vedea toate breakpoint-urile dintr-un proiect este nevoie sa deschidem fereastra "Breakpoints" din meniul "Debug->Windows->Breakspoints" sau folosind scurtatura "Ctrl+Alt+B". In aceasta lista putem in orice moment sa activam/ dezactivam un breakpoint, putem sa cautam un anumit breakpoint. Cea mai interesanta functionalitate mi se pare cea de import si export. Putem sa exportam o lista de breakpoint-uri pe care apoi o putem importa pe un alt calculator sau sa o folosim mai tarziu. Aceasta lista se salveaza sub forma unui fisier XML.
Cand suntem intr-un anumit breakpoint, fereastra "Imediate Windows" este extrem de utila pentru a putea executa cod scris la runtime. Trebuie sa avem grija ca nu putem sa scriem lambda expressions si sa le executam la runtime.
In mod normal cand suntem in debug, aplicatia noastra nu o sa se opreasca cand se arunca excepții care sunt mai tarziu prinse de catre codul nostru. Sunt insa cazuri cand vrem sa prindem si acest gen de exceptii. Pentru acest lucru avem la dispozitie fereastra "Exceptions" din "Debug->Exceptions" sau scurtatura "Ctrl+Alt+E". Putem selecta ca la anumite exceptii codul scris de noi sa se opreasca. In exemplul de mai jos pentru orice exceptie de tip AccessViolationException aruncata, care chiar daca exceptia este prinsa de sistemul nostru, aplicatie se opreste si putem face debug cand aceasta este aruncata.
Nu uitati ca in aceasta fereastra aveti disponibila funcionalitatea de cautare by name a unui excepti. Aceasta este extrem de utila cand vrem sa setam un comportament custom pentru o anumita exceptie, deoarece numarul acestora este foarte mare.
In momentul in care aplicatia noastra se afla intr-un anumit breakpoint, avem la dispozitie call stack-ul pentru a putea sa vedem de unde a fost apelat codul nostru. Folosind call stack-ul ne putem plimba pe acesta si sa vedem valoarea variabilelor din fiecare locatie. In fereastra "Locals" se pot observa toate variabilele locale, in functie de unde o sa fim pe stack o sa putem vedea variabilele pentru locatia respectiva din stack.
Fereastra "Autos" uneori poate sa fie extrem de utila, dar trebuie sa intelegem foarte bine ce afiseaza aceasta. In cadrul acestei ferestru o sa fie afisate variabilele, expresiile sau parametri care s-au modificat recent si pe care sistemul considera ca sunt relevanti. In cadrul ferestrei de "Watch" putem sa afisam orice expresie si sa urmarim cum se schimba aceasta valoare in timp ce face debug.
Pentru orice variabila, in debug, putem sa vedeam valoare acesteia, sa adaugam sau sa modificam aceasta valoare.
Cam atata ar fi despre base debugging stuff in Visual Studio. In urmatorul post de maine o sa vorbim despre multi-thread debugging, iar apoi despre Debugger Canvas.

Comments

  1. Si lista de shortcut-uri: http://msdn.microsoft.com/en-us/library/ms366733(v=vs.90) ;)

    ReplyDelete

Post a Comment

Popular posts from this blog

Windows Docker Containers can make WIN32 API calls, use COM and ASP.NET WebForms

After the last post , I received two interesting questions related to Docker and Windows. People were interested if we do Win32 API calls from a Docker container and if there is support for COM. WIN32 Support To test calls to WIN32 API, let’s try to populate SYSTEM_INFO class. [StructLayout(LayoutKind.Sequential)] public struct SYSTEM_INFO { public uint dwOemId; public uint dwPageSize; public uint lpMinimumApplicationAddress; public uint lpMaximumApplicationAddress; public uint dwActiveProcessorMask; public uint dwNumberOfProcessors; public uint dwProcessorType; public uint dwAllocationGranularity; public uint dwProcessorLevel; public uint dwProcessorRevision; } ... [DllImport("kernel32")] static extern void GetSystemInfo(ref SYSTEM_INFO pSI); ... SYSTEM_INFO pSI = new SYSTEM_INFO(

Azure AD and AWS Cognito side-by-side

In the last few weeks, I was involved in multiple opportunities on Microsoft Azure and Amazon, where we had to analyse AWS Cognito, Azure AD and other solutions that are available on the market. I decided to consolidate in one post all features and differences that I identified for both of them that we should need to take into account. Take into account that Azure AD is an identity and access management services well integrated with Microsoft stack. In comparison, AWS Cognito is just a user sign-up, sign-in and access control and nothing more. The focus is not on the main features, is more on small things that can make a difference when you want to decide where we want to store and manage our users.  This information might be useful in the future when we need to decide where we want to keep and manage our users.  Feature Azure AD (B2C, B2C) AWS Cognito Access token lifetime Default 1h – the value is configurable 1h – cannot be modified

What to do when you hit the throughput limits of Azure Storage (Blobs)

In this post we will talk about how we can detect when we hit a throughput limit of Azure Storage and what we can do in that moment. Context If we take a look on Scalability Targets of Azure Storage ( https://azure.microsoft.com/en-us/documentation/articles/storage-scalability-targets/ ) we will observe that the limits are prety high. But, based on our business logic we can end up at this limits. If you create a system that is hitted by a high number of device, you can hit easily the total number of requests rate that can be done on a Storage Account. This limits on Azure is 20.000 IOPS (entities or messages per second) where (and this is very important) the size of the request is 1KB. Normally, if you make a load tests where 20.000 clients will hit different blobs storages from the same Azure Storage Account, this limits can be reached. How we can detect this problem? From client, we can detect that this limits was reached based on the HTTP error code that is returned by HTTP