27. November 2009

SQL Statements um einen SQLServer-Trace aus einer Tabelle zu analysieren

Generellen Analysen:
SELECT
   Duration as DurationInMicroSeconds,  
   DATALENGTH(TextData) as len,
   CPU,
   Reads,
   Writes,
   TextData  
FROM
   trc_table01
WHERE
   TextData IS NOT NULL
order by duration desc;


SELECT
   AVG(Duration) as AVGDuration,
   AVG(READS) AS AVGReads,
   AVG(CPU) AS AVGCPU,
   COUNT(*) AS TotalStatements
   
FROM
   trc_table01   
WHERE
   TextData IS NOT NULL;


SELECT COUNT(*) AS NO_SQLSTATEMENTS_CPU_MORE_THAN_ZERO, AVG(CPU) AS AVG_CPU
FROM
   trc_table01
WHERE CPU>0
AND TextData IS NOT NULL;


Nach einem speziellen Teil suchen
SELECT
COUNT(CAST(TextData AS nvarchar(MAX))),
CAST(TextData AS nvarchar(MAX)) AS x
FROM
TRACETABLE
WHERE
TextData LIKE '%SUCHBEGRIFF%'
GROUP BY
CAST(TextData AS nvarchar(MAX))
ORDER BY
1 DESC

25. November 2009

Track Project Item ein-/ausschalten in VisualStudio

1.) Über die Options in VisualStudio kann man dauerhaft die Einstellung machen:








2.)Über ein Macro kann man in VisualStudio das aktuell gewählte Sourcefile im SolutionExplorer automatisch auswählen lassen. Dazu einfach einfach folgenden Code in ein Macro kopieren
DTE.ExecuteCommand("View.TrackActivityInSolutionExplorer")
und damit einen Button definieren. Darüber lässt sich das Feature dann auch wieder ausschalten.

3.)Mit dem Resharper geht es nocht bequemer: Einfach
SHIFT+ALT+L
drücken, dann navigiert der SolutionExlorer zum aktuell ausgewählten Codefile.

16. November 2009

VisualStudio RemoteDebugging zwischen zwei Domains

Will man mit VisualStudio RemoteDebugging zwischen zwei Rechnern betreiben, die in unterschiedlichen Domains sitzen, muss folgendes beachtet werden:

  • Auf dem Remote-Rechner (z.B. mit DNS-Name remoterechner.remotedomain) einen Domain-User anlegen (z.B: REMOTEDOMAIN\MYUSER01)
  • Auf dem Rechner mit VisualStudion einen lokalen(!) User anlegen (z.B: VS01\MYUSER01) mit gleichem Namen/Passwort
  • Mit dem Domain-User den MSVSMON starten (liegt im VisualStudio-Verzeichnis unter Common7\IDE\Remote Debugger\x86\msvsmon.exe, dieser kann z.B. per Share zugänglich gemacht werden) auf dem Remote-Rechner mit dem zu debuggenden Prozess starten.
  • VisualStudio auf dem anderen Rechner mit dem lokalen Benutzer VS01\MYUSER01 starten
  • Im Debuggin-Menüt "Attach to process" wählen. (Transport: Default, Qualifier: REMOTEDOMAIN\myuser01@remoterechner.remotedomain)
Alternative: 2 lokale Benutzer mit gleicher Userid/Passwort-Kombination (wenn beide keine DomainController sind)

Die PDBs des zu debuggenden Moduls müssen auf dem Zielrechner im GAC liegen. Das Modul sollte mit "DEBUG" in VisualStudio gebuildet werden, sonst kann es sein, dass nicht alle Variablenwerte im Debugger sichtbar sind (OPTIMIZED).

Hinweis: Wenn man mit z.B. VS 2008 debuggen möchte, muss man auch den RemoteDebugger aus dem VS 2008 Verzeichnis nehmen.

13. November 2009

LOG4NET erzeugt doppelte Einträge

Problem: Log4NET erzeugt doppelte Einträge

Ursache: Log4NET verhält sich anders als LOG4J. Wird ein Appender zweimal referenziert werden
die Einträge verdoppelt.
<root>
<level value="ERROR" />
<appender-ref ref="MyFileAppender" />
</root>
<logger name="Some.Logger" additivity="false">
<level value="INFO" />
<appender-ref ref="MyFileAppender" />
</logger>

Lösung: Ein Appender darf nur einmal definiert werden. Some.Logger erbt in diesem Fall von Root und schreibt dadurch in MyFileAppender
<root>
<level value="ERROR" />
<appender-ref ref="MyFileAppender" />
</root>
<logger name="Some.Logger" additivity="false">
<level value="INFO" />
</logger>

Stacktrace in .NET ausgeben

Console.Write(Environment.StackTrace);

11. November 2009

.NET Framework Versionen

Die genauen Versionen der installierten .NET Frameworks kann man am besten aus der Registry auslesen. Unter dem Key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP
finden sich die verschiedenen Frameworks als Unterordner (v1.1.x,v2.0.x,v3.0,v3.5).
Der relevante Schlüssel ist "Version".

Siehe auch http://msdn.microsoft.com/en-us/library/cc160716.aspx

9. Oktober 2009

NCover verwenden

NCover ist ein CodeCoverage-Analyse-Tool für Micrsoft.NET. Es ist unter http://www.ncover.com/download/current verfügbar. Dort kann man sich z.B. die CommunityEdition herunterladen und das MSI installieren.

NCover muss keinen Sourcecode verändern, es verwendet die Profiling-API des .NET Frameworks. Es kann also einfach auf eine Managed Exe angewendet werden. Folgender Aufruf ruft z.B. die nant.exe auf und läßt darüber UNIT-Tests laufen.
"c:\program files\ncover\NCover.Console.exe" ..\nant\bin\nant.exe -buildfile:Tests.build MeineUnitTests //x apitestoutput.xml //a MeineAssembly1;MeineAssembly2

//a gibt an für welche Assemblies die CodeCoverage analysiert werden soll.
//x ist das XML-Outputfile, das geschrieben wird.

Das erzeugte XML-Outputfile kann dann z.B. mit dem NCoverExplorer (Teil von TestDriven) visualisiert werden.

Sollte folgende Fehlermeldung kommen,
Profiled process terminated. Profiler connection not established
dann ist die NCover COM-Dll (CoverLib.dll) nicht registriert.

16. September 2009

Bind Failure Logging

[HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1

15. September 2009

PDB-Files bei ManagedCode

Eine PDB-Datei (program database file) enthält Debug- und Projektstatusinformationen.

Die Datei wird über den Switch /debug erzeugt.

  • /debug:full erzeugt Code, der debuggt werden kann.
  • /debug:pdbonly erzeugt PDBs, aber kein DebuggableAttribute (darüber erkennt der JIT compiler, dass Debug Infos enthalten sind)


In VisualStudio kann diese Einstellung in den Projekt-Settings/Build mit dem Button "Advanced" gemacht werden. (Drop-Down-Box DebugInfo)

PDB-Files können auch in den GAC kopiert werden (z.B. zum Debuggen). Dazu einfach in den Ordner c:\WINDOWS\assembly\GAC_MSIL\ wechseln, dort das Verzeichnis der Assembly in der gewünschten Version auswählen z.B. Feest.Common\6.3.0.3472__2aa8ae3ddce4beba\) und dort das .PDB-File der Assembly kopieren.

11. September 2009

.NET Framework Sourcen debuggen mit VisualStudio

Hier gibt es eine Anleitung, wie man den MS SourceCode-Server einrichtet, um .NET Framework Klassen unter VisualStudio zu debuggen.

2. September 2009

Set in C#

Bis .Net 2.0 gibt es keine Set-Klasse (analog zum Java-Set, eine Collection-Klasse, die doppelte Einträge ausschließt). Alternativ kann man hier auf die PowerCollection zurückgreifen.

Ab .NET 3.5 gibt es z.B. die HashSet-Klasse

3. August 2009

Wie kann man mit dem Silverlight Datagrid Daten aus einem Java-Web-Service anzeigen und editieren

In meinem MSDN Solve Code Clip wird ein RESTful JavaWebService mit dem AXIS2 Framework unter Eclipse erstellt. Dieser ermöglicht den DB-Zugriff per JPA auf eine SQL-Server Tabelle. Im zweiten Teil wird ein Silverlight Control erstellt, das die Daten des Java WebServices in einem DataGrid anzeigen und ändern kann.

16. Juli 2009

Page Scope mit JSF

Problem: Wie kann man in JSF Listen, die z.B. von Tabellen-Controls visualisiert werden in den Page Scope legen (sprich länger als der Request Scope, aber kürzer als den Session Scope, so dass Post Backs funktionieren, ohne die Datenbinding zu verlieren) ?

Lösung:
Vor JSF 2.0 gibt es mit Apache Tomahawk die Möglichkeit den Zustand einer Request-Scope Bean

<managed-bean>
<managed-bean-name>model_application</managed-bean-name>
<managed-bean-class>
de.rfeest.demo.web.backing.ApplicationModel</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

in den Viewstate einer Page zu setzen
<t:saveState value="#{model_application}" id="ss1"/>

und im Tabellen-Control verwenden:
<af:table emptyText="No items were found" value="#{model_application.appStatusList}" ...


Mit JSF 2.0 wird der View Scope eingeführt, der das ganze in JSF nativ integriert.

23. Juni 2009

Auf Fehler im DataBinding reagieren

Zunächst muss mann sich auf das BindingComplete-Event des DataBindings registrieren, das die Fehler werfen kann.
wertTextBox.DataBindings[0].BindingComplete += new BindingCompleteEventHandler(wertTextBox_BindingComplete);

Der Event-Handler kann dann folgendemaßen aussehen:
private void wertTextBox_BindingComplete(object sender, BindingCompleteEventArgs e)
{

if (e.BindingCompleteState != BindingCompleteState.Success)
{
errorProvider1.SetError(wertTextBox, e.ErrorText);
}
else
{
errorProvider1.SetError(wertTextBox, null);
}
}

19. Juni 2009

Vista: Unbekannter Fehler bei der Systemwiederherstellung

Problem: Es tritt bei der Einspielen eines Wiederherstellungspunkts mit Windows Vista folgender Fehler auf: "Unbekannter Fehler bei der Systemwiederherstellung" und nichts wurde verändert.

Lösung: Den Wiederherstellungspunkt beim Starten über F8 wiederherstellen, dann tut´s.

Eclipse WTP: Hotdeploy mit Tomcat ohne Restart

Problem: Eine geänderte JSP wird beim gestarteten Tomcat in Eclipse WTP nicht aktualisiert.

Ursache: in der context.xml ist folgender Eintrag

<Context antiResourceLocking="true"....>

Lösung:

antiResourceLocking muss raus, damit er JSPs nicht in den Temp-Ordner schreibt.

21. Mai 2009

Einen WindowsService installieren oder deinstallieren

installieren
installutil /name=myservicename myservice.exe


deinstallieren:
installutil /u /name=myservicename  myservice.exe

NullableDateTimePicker

Problem: Der DateTimePicker bietet keine einfache Lösung einen Null-Wert an ein DataBinding zu übermitteln.

Lösung: Erweiterung der DateTimePicker-Klasse um eine NullableValue-Property. Diese muss anstatt der Value-Property für das DataBinding verwendet werden.

  /// 
/// Erweitert den DateTimePicker um eine Nullable Property.
///

public class NullableDateTimePicker: DateTimePicker
{
///
/// Diese Property muss beim DataBinding anstatt der Property
/// Value verwendet werden.
///

public object NullableValue
{
// Nur wenn die Checkbox angehakt ist, den Wert des
// DateTimePicker zurückgeben, ansonsten null
get
{
if (Checked)
{
return Value;
}
else
{
return null;
}
}

// Der Wert des DateTime-Pickers darf nur gesetzt werden,
// wenn der übergebene Wert (value) nicht null ist.
// Ansonsten wird das aktuelle Datum gesetzt und
// die Checkbox auf nicht angehakt gesetzt.
set
{
if (value is DateTime)
{
Value = (DateTime) value;
Checked = true;
}
else
{
Value = DateTime.Now;
Checked = false;
}
}
}
}

13. Mai 2009

MaxIdle im Tomcat-Connection Pool

Einstellung für unlimited Connections im Pool unterscheiden sich in den Tomcat-Versionen:
maxIdle=0 bei Tomcat 4
maxIdle=-1 ab Tomcat 5

Anmerkung: maxIdle=0 würde ab Tomcat 5 das ConnectionPooling abschalten!

Changelists .NET Framework Service Packs

.NET Framework 3.5 Service Pack 1

.NET Framework 3.0 Service Pack 1

.NET Framework 2.0 Service Pack 1

12. Mai 2009

Toolbar/Menü-Button-Event und BindingSource - Problem

Problem: In einem Form werden Daten nicht persistiert, die über an eine BindingSource gebundenes Control editiert wurden, wenn über einen Toolbar- oder Menu-Button das Speichern ausgelöst wird.

Ursache: Toolbars oder Menüs wechseln den Focus nicht. Das ValidateEvent im Control wird deswegen nicht ausgelöst und kann seine Änderungen nicht an die BindingSource schicken. Der EndEdit-Aufruf auf der BindingSource ist dann wirkungslos.

Lösung: Bevor das Speichern über ein Event aus einem Toolbar- oder Menüpunkt ausgelöst wird, muss dort explizit der Fokus geholt werden über die Focus()-Methode. Danach sorgt ein Aufruf der EndEdit-Methode auf der BindingSource auch dafür, dass die eingebenen Daten in die Quelle (DataSource/DataTable) gelangen.

19. März 2009

Hibernate Statistic MBean mit Spring registrieren

Folgender Eintrag muss in die beans.xml:
<bean name="HibernateMBean"
class="com.myorg.mbean.HibernateStatistic"
init-method="init">
<property name="entityManagerFactoryForJMX"
ref="entityManagerFactory" />
</bean>

<bean class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry
key="com.myorg.myapp:Name=HibernateMBean"
value-ref="HibernateMBean">
</entry>
</map>
</property>
</bean>


Die Klasse HibernateStatistic sieht so aus
/**
* Dient der Erzeugung einer HibernateStatistik MBean aus einer JPA EntityManagerFactory. Der Klasse muss eine
* EntityManagerFactory übergeben. Die Klasse selbst kann dann als MBean registriert werden. Sie bietet alle
* Getter/Setter von StatisticsService an. Dann muss die
*
* @author feestra
*
*/
public class HibernateStatistic extends StatisticsService {

/**********************************************************************************************************
* Logger for this class
*/
private static Logger logger = Logger.getLogger(HibernateStatistic.class);
/**********************************************************************************************************
* Wird benötigt für JMX-Hibernate-Statistik.
*/
private EntityManagerFactory entityManagerFactoryForJMX;

private StatisticsService statisticsService;

/**********************************************************************************************************
* Leere Kontruktor. EntityManagerFactory muss über Setter gesetzt werden, dann die init()-Methode
* aufgerufen werden.
*/
public HibernateStatistic() {

}

/**
* EntityManagerFactory über Konstruktor uebergeben, fuehrt dann gleich die init()-Methode auf, um die
* StatisticsService-Instanz zu initialisieren.
*
* @param emf
*/
public HibernateStatistic(EntityManagerFactory emf) {
this.entityManagerFactoryForJMX = emf;
init();
}

public void init() {
EntityManager em = null;
try {

em = getEntityManagerFactoryForJMX().createEntityManager();

StatisticsService statsMBean = new StatisticsService();
Session session = (Session) em.getDelegate();
statsMBean.setSessionFactory(session.getSessionFactory());
statsMBean.setStatisticsEnabled(false);
logger.debug("createHibernateMBeanForJPA was fine.");
statisticsService = statsMBean;

} catch (Exception e) {
logger.error("createHibernateMBeanForJPA failed", e);

} finally {
if (em != null) {
em.close();
}
}
}
...
}

4. März 2009

JPA: Sequences mit Oracle

Problem: Wenn man mit JPA und einer Oracle-Datenbank @GeneratedValue(strategy=GenerationType.SEQUENCE,...) verwendet, werden merkwürdige PKs erzeugt, die nichts mit dem Wert aus der Oracle-Sequence zu tun haben.

Lösung: strategy=GenerationType.SEQUENCE weglassen, da dies intern ein HILO-Verfahren verwendet und nicht jedes Mal die Sequence befragt:

@Id
@GeneratedValue(generator="myseq")
@SequenceGenerator(name="myseq",sequenceName="MY_SEQ")
@Column(name = "PK_MY_TABLE", unique = true, nullable = false, precision = 11, scale = 0)
public long getPkMyTable() {
return this.pkReprData;
}

3. März 2009

JPA/Hibernate sortierte Collections

Problem: Collections einer Entität werden nicht sortiert, obwohl in der Query ein "order by" steht.

Ursache: In der POJO-Klasse ist die Collection als Set definiert.

Lösung: Anstatt des Set einfach eine List verwenden. Die Hibernate Tools generieren leider per Default ein Set.

Dies kann im Build-File z.B. durch folgende zwei Tasks geändert werden:
<replace summary="true" dir="src-orm/com/myorg/dataaccess/orm" token="HashSet" value="ArrayList" />
<replace summary="true" dir="src-orm/com/myorg/dataaccess/orm" token="Set" value="List" />

17. Februar 2009

Batchfile läßt sich als Schedulded Task unter Windows 2003 nicht ausführen

Problem: Ein Batchfile läßt sich als Schedulded Task unter Windows 2003 nicht ausführen, wenn der ausführende Benutzer nicht Mitglied der Gruppe Administratoren ist.

Im Error-Log der ScheduledTask-Anwendung steht 0x80070005: Access is denied.

Lösung: Dem User müssen Ausführungsrechte auf die cmd.exe gegeben werden.

4. Februar 2009

Tabellen mit Oracle 10g endgültig löschen

Problem:
drop table
löscht ab Oracle 10g die Tabellen nicht mehr, sondern verschiebt sie in den Papierkorb. Tabellen heißen dann BIN$<irgendeinstring>.

Lösung:
Tabellen müssen mit
PURGE TABLE
gelöscht werden. Den kompletten Papierkorb eines Benutzers löscht man mit
PURGE RECYCLEBIN
. Alle Papierkörbe können mit
PURGE dba_recyclebin
gelöscht werden.

18. Januar 2009

.NET Dumps mit WinDbg analysieren

Mit WinDbg (Teil der Windows Debugging Tools) kann man auch .NET Dumps analysieren. Dazu muss es am besten mit der "Visual Studio Eingabeaufforderung" gestartet werden (so sind alle notwendigen Pfade automatisch gesetzt.

Dort kann einen zuvor mit adplus erstellten Dump laden.

Zunächst muss die Managed-Unterstützung geladen werden über die WinDbg-Kommadozeile
.loadby sos mscorwks
Eventuell fehlen hier Symbole. Sollte das der Fall sein, dann einfach im Menü File->Symbol Path auswählen und dort zusätzlich
http://msdl.microsoft.com/download/symbols
eintragen, dann werden die benötigten Symbole einfach von Microsoft heruntergeladen.


Sollte das System, auf dem der Dump gemacht wurde und das System, auf dem der Dump analysiert werden soll sich in der .NET Framework Version (auch nur minimal) unterscheiden, so muss die Datei mscordacwks.dll des gedumpten Systems in den Symbol-Pfad mit dem Namen
mscordacwks_<arch>_<arch>_<version>.dll
aufgenommen werden. (Siehe auch http://blogs.msdn.com/b/tom/archive/2008/04/09/asp-net-tips-getting-sos-to-work-when-commands-fail.aspx)


Heap analysieren
!DumpHeap
liefert z.B.: folgende Ausgabe:
MT    Count    TotalSize Class Name
6ef5fba8       73         4088 System.Reflection.RuntimeMethodInfo
68634fb4       28         4144 System.Data.DataColumn
68df1488       61         4392 System.Windows.Forms.PropertyStore+ObjectEntry[]
6ef60508      392         4704 System.Object
6ef62f40       92         5152 System.Collections.Hashtable
68635d88        5         5180 System.Data.RBTree`1+Node[[System.Data.DataRow, System.Data]][]
6b5f8c4c       95         5320 System.Configuration.FactoryRecord
6ef62a88       89         5576 System.Int32[]
6ef4c47c      230         6440 System.Security.SecurityElement
6ef61a6c      369         7380 System.RuntimeType
6ef6151c       81         9880 System.Char[]
68636e00       10        10360 System.Data.RBTree`1+Node[[System.Int32, mscorlib]][]
6ef6335c       79        17652 System.Byte[]
6ef6303c       93        21240 System.Collections.Hashtable+bucket[]
6ef62b38     4643        55716 System.Int32
68636f00     2311        64708 System.Data.RBTree`1+RBTreeEnumerator[[System.Data.DataRow, System.Data]]
6ef340bc      627        75216 System.Object[]
6ef5a930     2328        83808 System.Collections.Hashtable+HashtableEnumerator
68df5158     9246       110952 System.Windows.Forms.Control+MultithreadSafeCallScope
6ef6291c     5017       120408 System.Collections.ArrayList
6ef62c14     4622       129416 System.Collections.ArrayList+ArrayListEnumeratorSimple
6ef60a28    11593       231860 System.Text.StringBuilder
6ef608ec    18367      1163300 System.String


Dump aller Objekte im LargeObjectHeap
!dumpheap -min 85000



Threadstack analysieren
Liste der CLR Threads
!threads
anzegen:
PreEmptive   GC Alloc           Lock
ID OSID ThreadOBJ    State     GC       Context       Domain   Count APT Exception
0    1 10c4 0026a4f0      6020 Enabled  0211b030:0211ca74 00266280     0 STA
2    2 1124 002779c0      b220 Enabled  00000000:00000000 00266280     0 MTA (Finalizer)
3    3 1360 002f4078   880b220 Enabled  00000000:00000000 00266280     0 MTA (Threadpool Completion Port)
4    4 1368 002f6d58    80a220 Enabled  00000000:00000000 00266280     0 MTA (Threadpool Completion Port)


Dort wählt man sich den gewünschten Thread aus über
~<ID>s
, also um den Thread mit der ID 0 anzuschauen gibt man
~0s
ein. Dann kann man sich mit
!CLRStack
nur Managed Stack ausgeben lassen, was z.B. zu folgender Ausgaben führt:
SharpShutdown+0x1632e (012f632e)
Priority: 0  Priority class: 32  Affinity: 3
0:000> !clrstack -p
OS Thread Id: 0x10c4 (0)
ESP       EIP
0016f240 775a9a94 [InlinedCallFrame: 0016f240] System.Windows.Forms.UnsafeNativeMethods.WaitMessage()
0016f23c 68da8e48 System.Windows.Forms.Application+ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32, Int32, Int32)
PARAMETERS:
this = 0x01f68694
dwComponentID = 
reason = 0xffffffff
pvLoopData = 0x00000000

0016f2d8 68da8937 System.Windows.Forms.Application+ThreadContext.RunMessageLoopInner(Int32, System.Windows.Forms.ApplicationContext)
PARAMETERS:
this = 0x01f3ef78
reason = 0xffffffff
context = 0x01f634b8

0016f32c 68da8781 System.Windows.Forms.Application+ThreadContext.RunMessageLoop(Int32, System.Windows.Forms.ApplicationContext)
PARAMETERS:
this = 
reason = 
context = 

0016f35c 68d65911 System.Windows.Forms.Application.Run(System.Windows.Forms.Form)
PARAMETERS:
mainForm = 

0016f370 00eac769 DE.RFeest.Tools.SharpShutdown.Program.Main()

CPU-Zeit der einzelnen Threads
!runaway
User Mode Time
Thread       Time
12:1818      0 days 0:02:46.359
25:1164      0 days 0:02:42.859
31:1d54      0 days 0:01:05.421
33:140c      0 days 0:01:03.031
34:794       0 days 0:00:55.562
30:120c      0 days 0:00:53.031
32:1980      0 days 0:00:49.937
37:1900      0 days 0:00:42.640
38:1dc8      0 days 0:00:41.984
17:1da0      0 days 0:00:35.156
14:1bb0      0 days 0:00:34.937
15:1848      0 days 0:00:34.546
16:8fc       0 days 0:00:34.109
39:1398      0 days 0:00:29.140
35:7f4       0 days 0:00:27.015
40:1270      0 days 0:00:26.625
36:1908      0 days 0:00:17.781
Details zu einer Managed-Exeception
29   18 1458 2039df38   180b220 Enabled  0e15d56c:0e15d57c 00109f58     3 MTA (Threadpool Worker) System.OutOfMemoryException (05c6c578)
kann man sich über
!pe
anzeigen lassen:
Exception object: 126449bc
Exception type: System.OutOfMemoryException
Message: 
InnerException: 
StackTrace (generated):
SP       IP       Function
7C7EE5A4 792F110C mscorlib_ni!System.Reflection.Assembly.nLoad(System.Reflection.AssemblyName, System.String, System.Security.Policy.Evidence, System.Reflection.Assembly, System.Threading.StackCrawlMark ByRef, Boolean, Boolean)+0x2c
7C7EE5CC 792D5B58 mscorlib_ni!System.Reflection.Assembly.InternalGetSatelliteAssembly(System.Globalization.CultureInfo, System.Version, Boolean)+0xd8
7C7EE5F0 792D4000 mscorlib_ni!System.Resources.ResourceManager.GetSatelliteAssembly(System.Globalization.CultureInfo)+0x50
7C7EE61C 792821AC mscorlib_ni!System.Resources.ResourceManager.InternalGetResourceSet(System.Globalization.CultureInfo, Boolean, Boolean)+0x12c
7C7EE670 792822C8 mscorlib_ni!System.Resources.ResourceManager.InternalGetResourceSet(System.Globalization.CultureInfo, Boolean, Boolean)+0x248
7C7EE6C4 7928190B mscorlib_ni!System.Resources.ResourceManager.GetString(System.String, System.Globalization.CultureInfo)+0x4b
7C7EE6E4 6522C3ED System_Data_ni!System.Data.Res.GetString(System.String)+0x1d
7C7EE6F0 654CD912 System_Data_ni!System.Data.Common.ADP.PooledOpenTimeout()+0x12
7C7EE700 656C70B4 System_Data_ni!System.Data.ProviderBase.DbConnectionFactory.GetConnection(System.Data.Common.DbConnection)+0x4a36e4
7C7EE720 65223846 System_Data_ni!System.Data.ProviderBase.DbConnectionClosed.OpenConnection(System.Data.Common.DbConnection, System.Data.ProviderBase.DbConnectionFactory)+0x76
7C7EE754 6521DF06 System_Data_ni!System.Data.SqlClient.SqlConnection.Open()+0xf6
...
StackTraceString: 
HResult: 8007000e
Anaylse von aufgezeichneten Exceptions Wenn folgendes von windbg ausgegeben wird:
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
kann man eine Analyse dieser Exception ausführen:
!analyze -v
Siehe auch: http://msdn.microsoft.com/en-us/magazine/cc163528.aspx http://www.informit.com/articles/article.aspx?p=1409801&seqNum=4 http://msdn.microsoft.com/en-us/library/bb190764.aspx http://blogs.msdn.com/b/alejacma/archive/2009/08/13/managed-debugging-with-windbg-managed-heap-part-1.aspx http://www.zhaun.net/post/Debugging-NET-virtual-memory-fragmentation-with-WinDbg.aspx http://www.codeproject.com/KB/dotnet/BestPractices5.aspx#WhatisthetypeofmemoryleakTotalMemoryManagedmemoryunmanagedmemory

Dumps mit dem .NET Framework erstellen

Mit ADPlus (Teil der Windows Debug Tools) kann man Dumps (enthält u.a. HeapDump und ThreadDump) eines laufenden Prozesses machen:

Dump eines Prozessed mit einer speziellen ID
adplus -Hang -o . -p 3720
Dump aller Prozesse mit einem speziellen Namen (hier die IIS Prozesse)
adplus -Hang -o . -pn w3wp.exe
Der Dump kann dann mit WinDbg (ebenfalls Teil der Windows Debug Tools) oder einem kommerziellen Tool wie MemProfiler analysiert werden.

16. Januar 2009

Mehr als 4GB mit 32Bit Windows

Unter Windows (z.B. mit Windows 2003 Enterprise Edition) kann mehr als 4GB adressiert werden. Auch mit der 32 Bit Variante. Das Stichwort lautet hier /pae (Physical Address Extension). Wichtig: PAE ermöglicht nur in Summe (der Prozesse) über die 4GB zu kommen, nicht pro Prozess - 1 Prozess mit 10GB, also z.B. 10 Prozesse mit 1 GB). Dazu ist aber keine Codeänderung notwendig.

Unter diesen Links finden sich mehr Informationen zu PAE:
PAE 1
PAE 2

Genaue Systeminfo unter Windows

Mit dem Befehl
systeminfo
kann man sich genaue Infos über das Window-System geben lassen (z.B. Anzahl der Prozessoren, 32 oder 64bit Prozessor, Bios-Version, etc.

13. Januar 2009

DDLs generieren mit DB2

Mit dem Tool db2look (z.B. bei Windows IBM\Sqllib\BIN\db2look.exe) können DDLs generiert werden. Am besten direkt auf dem DBServer ausführen.

db2look -d [dbname] -i [dbuser] -w [password] -o myfile.ddl -e -z [schema]

Variablen:
[dbname] : Datenbank, zu der man sich verbinden will
[dbuser] : DB-Benutzer
[password] : Password des DB-Benutzers
[schema] : Schema, das exportiert werden soll

5. Januar 2009

Kein MMC-Plugin für .NET Framework 3.0 / 3.5

Problem: Es gibt zwar die Ordner
C:\Windows\Microsoft.NET\Framework\v3.5
und
C:\Windows\Microsoft.NET\Framework\v3.0
Dort ist aber keine Konfigurationsdatei machine.config. Genauso fehlt das MMC-Plugin

Lösung: Weder .Net 3.0 noch 3.5 sind Stand-Alone-Versionen. Beide benötigen das .NET Framework 2.0. Konfiguartionen müssen also über die 2.0-Infrastruktur abgehandelt werden.

4. Januar 2009

ASP.NET Control führt in der VisualStudio-Entwurfsansicht zu Fehler

Problem: In einem ASP.NET Projekt wird versucht in der Designansicht ein Control auf ein WebForm zu ziehen. Das ist nicht möglich. Über die Quellansicht läßt sich das Control zwar hinzufügen, in der Design Ansicht erhält man jedoch folgende Fehlermeldung
Fehler beim Erstellen des Steuerelements... Webprojektelement "... " kann nicht gefunden werden.


Ursache: Der Designer scheint Probleme mit Sonderzeichen wie dem # (Sharp) zu haben. Kommt so ein Sonderzeichen im Pfad zur aspx.-Datei vor führt es zu dem oben beschriebenen Fehler.

Lösung: Die Sonderzeichen aus dem Pfad weglassen. Leider gibt´s wohl keine andere Möglichkeit.