NSIS에서 따옴표(double quote) 사용하기

NSIS 2008. 3. 5. 23:45 posted by deneb
원문 : http://nsis.sourceforge.net/How_can_I_use_quotes_in_a_string

따옴표 종류는 작은 따옴표(single quote) (') 와 큰 따옴표(double quote) (")로 구분되고
보통 C언어에서는 역슬래쉬(\)뒤에 오면 문자열로 간주한다.
이것을 생각하고 작성하는데 결코 NSIS 스크립트에서는 아니더라...

예제를 살펴보면

MessageBox MB_OK "I'll be happy" ; 더블로 묶고 싱글이 들어가면 문자열
MessageBox MB_OK 'And he said to me "Hi there!"' ; 싱글로 묶고 더블이 들어가면 문자열
MessageBox MB_OK `And he said to me "I'll be damned!"` ; '(1번 왼쪽의 키다)으로 묶으면 싱글, 더블 모두 문자열
MessageBox MB_OK "$\"A quote from a wise man$\" said the wise man" ; 역슬래쉬 앞에 $를 사용하며면 그 뒤의 문자를 문자열로 인식
MessageBox MB_OK "That would be $$60" ; $표시를 하려면 $$로 하면 된다.

보통 escape character, escaping string은 언어의 기본적인 처리에 있어서 아주 중요한데
UI나 다른 컴퓨터 및 서버로 문자열을 전달시 잡기 힘든 버그로 나타나기 아주 쉽기 때문이다.

언어마다 매번 찾아보고 실수를 연발하는데
역시나 기본이 중요하다는 것을 새삼 느끼게 된다.
출처 : http://support.microsoft.com/kb/925336

Error message when you try to install a large Windows Installer package or a large Windows Installer patch package in Windows Server 2003 or in Windows XP: "Error 1718. File was rejected by digital signature policy"

SYMPTOMS

When you try to install a large Microsoft Windows Installer (.msi) package or a large Microsoft Windows Installer patch (.msp) package on a computer that is running Microsoft Windows Server 2003 or Microsoft Windows XP, you receive the following error message:
Error 1718. File FileName was rejected by digital signature policy.


CAUSE

This problem occurs when the computer has insufficient contiguous memory for Windows Server 2003 or Windows XP to verify that the .msi package or the .msp package is correctly signed.

WORKAROUND

To work around this problem, follow these steps:

1. Click Start, click Run, type control admintools, and then click OK.
2. Double-click Local Security Policy(로컬 보안 설정).
3. Click Software Restriction Policies(소프트웨어 제한 정책).
Note If no software restrictions are listed, right-click Software Restriction Policies(소프트웨어 제한 정책), and then click Create New Policy(정책 생성하기).
4. Under Object Type(개체 유형), double-click Enforcement(강요).
5. Click All users except local administrators(로컬 관리자를 제외한 모든 사용자), and then click OK.
6. Restart the computer.

Important
After you follow the previous steps, local administrators can install the .msi package or the .msp package. After the package is installed, reset the enforcement level by following the previous steps. In step 5, click All users instead of All users except local administrators.

MORE INFORMATION

Digital signatures help make sure that a package has not been tampered with. Windows Server 2003 and Windows XP use an additional level of security, Software Restriction Policies, when Windows Installer calls the SaferIdentifyLevel function.

When Windows Installer calls the SaferIdentifyLevel function together with the SAFER_CRITERIA_IMAGEHASH flag, the whole package is loaded into memory on the computer. The computer must have sufficient contiguous memory for the package size. If the computer has insufficient contiguous memory, an error occurs. Because an error occurs, Windows Installer cannot verify that the package is correctly signed. Therefore, you receive the error message that is mentioned in the "Symptoms" section.

The following log data shows the sequence of events when this problem occurs:
MSI (s) (BA:AD) [12:00:00:000]: SOFTWARE RESTRICTION POLICY: Verifying object --> 'D:\WINDOWS\Installer\50baad.msp' against software restriction policy
MSI (s) (BA:AD) [12:00:00:000]: SOFTWARE RESTRICTION POLICY: D:\WINDOWS\Installer\50baad.msp has a digital signature
MSI (s) (BA:AD) [12:00:00:000]: SOFTWARE RESTRICTION POLICY: SaferIdentifyLevel reported failure. Assuming untrusted. . . (GetLastError returned 5)
MSI (s) (BA:AD) [12:00:00:000]: The installation of D:\WINDOWS\Installer

Using COM to explore the namespace

Windows 2007. 2. 8. 11:23 posted by deneb

출처 : http://netez.com/2xExplorer/shellFAQ/bas_xplore2.html

There are no two ways about it, using low-level COM to enumerate folders is quirky. Note that I didn't say "difficult", it just takes some time getting used to it. With COM you have to manage objects yourself: create the right one, ask for a specific interface for the functionality you are after, then use it and finally take care to release it. In contrast, in regular API-based programming the operating system is doing the management for you; you just call functions directly, oblivious about objects and things behind the scenes.

To enumerate a folder via COM, you need an IShellFolder pointer to the folder object you're after. We've seen a sketch of how to obtain this interface by parsing a path name in the previous section. The next step is to ask the object to enumerate itself using its EnumObjects method, which creates a new object which exposes an IEnumIDList interface. This enumerator object has the contents we are after, as a collection of local PIDLs, one for each item in the folder.

The best way to illustrate all this is with an example. Let's try to create the COM-equivalent of the EnumerateFolderFS() sample presented earlier, which read the contents of a filesystem folder given a full path to it. The following EnumerateFolder() sample produces the same results in a completely different approach.

#include <shlobj.h>

void EnumerateFolder(LPCTSTR path)
{
   HRESULT hr; // COM result, you'd better examine it in your code!
   hr = CoInitialize(NULL); // initialize COM
   // NOTE: usually COM would be initialized just once in your main()

   LPMALLOC pMalloc = NULL; // memory manager, for freeing up PIDLs
   hr = SHGetMalloc(&pMalloc);

   LPSHELLFOLDER psfDesktop = NULL; // namespace root for parsing the path
   hr = SHGetDesktopFolder(&psfDesktop);

   // IShellFolder::ParseDisplayName requires the path name in Unicode.
   OLECHAR olePath[MAX_PATH]; // wide-char version of path name
   MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, path, -1, olePath, MAX_PATH);

   // parse path for absolute PIDL, and connect to target folder
   LPITEMIDLIST pidl = NULL; // general purpose
   hr = psfDesktop->ParseDisplayName(NULL, NULL, olePath, NULL, &pidl, NULL);
   LPSHELLFOLDER psfFolder = NULL;
   hr = psfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, 
                                 (void**)&psfFolder);
   psfDesktop->Release(); // no longer required
   pMalloc->Free(pidl);

   LPENUMIDLIST penumIDL = NULL; // IEnumIDList interface for reading contents
   hr = psfFolder->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 
                               &penumIDL);
   while(1) {
      // retrieve a copy of next local item ID list
      hr = penumIDL->Next(1, &pidl, NULL);
      if(hr == NOERROR) {
         WIN32_FIND_DATA ffd; // let's cheat a bit :)
         hr = SHGetDataFromIDList(psfFolder, pidl, SHGDFIL_FINDDATA, &ffd, 
                                  sizeof(WIN32_FIND_DATA));

         cout << "Name = " << ffd.cFileName << endl;
         cout << "Type = " << ( (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                                ? "dir\n" : "file\n" );
         cout << "Size = " << ffd.nFileSizeLow << endl;
         
         pMalloc->Free(pidl);
      }
      // the expected "error" is S_FALSE, when the list is finished
      else break;
   }

   // release all remaining interface pointers
   penumIDL->Release();
   psfFolder->Release();
   pMalloc->Release();

   CoUninitialize(); // shut down COM
}

Oh dear, that sure was hard work. 56 lines of code to do exactly the same thing EnumerateFolderFS() managed in just 23 lines — less than half. But hey, that's C++ baby, either take it or leave it and join the VB club <g>. Since this is the first real COM example I presented, I'll try to be gentle and explain it thoroughly. Many typical issues in COM programming appear in this code:

  • COM initialization. Before you use any of the COM services and objects you need to call CoInitialize. Conversely, after you're done with COM you must call CoUninitialize. Typically an application that relies heavily on COM will initialize the subsystem just once when it starts, not inside each function that utilizes COM. Still it's no harm calling CoInitialize more than once, as long as it is balanced by a CoUninitialize.
    ADVANCED. If your program is multi-threaded, then COM must be initialized in each thread that uses its services. Initializing it once in the main thread won't be enough.
  • Object management. The code sample used four distinct COM objects to read the folder contents. Using desktop's IShellFolder the path was parsed, generating a pidl to the target folder. This second object was created using desktop's BindToObject. The enumerator (third object, the one we were after all along) was created by EnumObjects. Finally the shell memory manager was created by SHGetMalloc to free the various PIDLs that were allocated for us. All COM objects are dynamically created and must be released to free up the associated memory and resources via the object's Release method, inherited from IUnknown. Note that PIDLs are not objects, only pointers to allocated memory. That's why they are Free'd and not Release'd, something that took me some time to realise in the early dayz.
  • UNICODE strings. In case you haven't heard about them, UNICODE strings have wide characters, i.e. 2-bytes each. Apparently the orientals are responsible for this major upset <g>. COM has adopted the UNICODE system whole-heartedly, and most system (and shell) objects expect strings to be wide. The problem is that windows 95/98 (dunno about Me) work with multibyte strings, which are basically regular single-byte strings, despite what their name suggests. If you want your proggy to work in all windows platforms then you'd have to stick with single-byte strings and do manual conversions whenever a wide string is required. That is exactly what MultiByteToWideChar function does above. If you use MFC, you can take advantage the CString class, which simplifies string management and conversions. The drawback is the performance penalty involved for all these conversions; unfortunately there's no way around it, except if you are willing to distribute separate ANSI and UNICODE versions of your programs.
  • Enumerators. These fancy-name objects are frequent denizens of the COM landscape. Any VB people in the audience will be familiar with the term collections. Enumerators are simple objects that hold collections of similar items. The internal organization is transparent; enumerators expose an IEnumxxx interface, as IEnumIDList. Once initialized, items can be accessed sequentially by calling the Next method repeatedly, until some error indicates that the list is exhausted. Personally I feel it's a grand omission that all those objects don't have a method like Count to give the total number of elements in the list. An important detail is that enumerators usually return duplicates of their listed items which you are responsible to cleanup. In the code sample above note that each pidl is Free'd after use.

You can now appreciate why people say that COM is a technology with a steep learning curve. One has to be familiar with dozens of details before even the simplest "Hello COM" program can be build. And you'd better hurry in that climbing while learning, because mikro$oft have already prepared the COM+ mountain for you to climb next, slippery slopes an'all. Will this torment ever end? <g>

Of course, these issues are all for starters. The main dish is learning about all the COM objects supplied by the framework, finding out what they can do for you, and how to work with them, what interfaces they support, etc. The online documentation is guaranteed to be the most complete and up-to-date source of reference information. As they say, if you don't like reading, probably software development is not your ideal vocation. What you read in that good book published in 1998 may already be obsolete, plus there will be dozens of new objects introduced since then.

ADVANCED: Fending for your address space
You may have noticed in the sample code the abundance of NULL arguments to interface methods, most of the time implying a default action. Although this is easy to do, there's a possible risk here, if the NULL is a pointer meant to receive some result from the method. Take for example pdwAttributes parameter of ParseDisplayName. The docs state clearly that by passing NULL you specify that are not interested to receive any attributes at this time. In an ideal world you would be safe, but in this world there are many cowboys out there developing shell and namespace extensions, who wouldn't think twice before attempting to write on a NULL pointer without doing the proper checks first. Since that offending amateur object runs in the same address space as your app, it will drag you down in its demise. The workaround is to provide dummy variables for all such potential trouble-makers; for our example this would mean defining a "DWORD dummyAttrs = 0;" and passing it on to ParseDisplayName, even if you don't have any intention of using it in the end.

Ok, but what about that namespace exploring?

Sorry folks, I got a bit carried away there. So, let's get back to the subject, folder contents enumeration. The EnumerateFolder() sample will produce almost the same results as a the filesystem version EnumerateFolderFS(). Even the order of the items is the same, which hints that EnumObjects down deep must be using FindFirstFile et al for doing the actual folder reading. But almost the same implies there are some differences:

  • We no longer read the '.' and '..' pseudo-items. That's progress since I consider these two plain nuisances. <g>
  • We don't get automatic filename filtering; the best we can do is specify whether we want files, folders or both, via the SHCONTF_FOLDERS and SHCONTF_NONFOLDERS flags that EnumObjects understands.

The most important difference however, is the file date/time information. SHGetDataFromIDList doesn't fill in the file details in WIN32_FIND_DATA as thoroughly as an equivalent FindFirstFile would. Only the modification date is filled in, and even that is rounded to the nearest even second. That's the reason why I mentioned that you need both COM and traditional API to obtain complete information for filesystem folders.

ADVANCED: Stale PIDLs
SHGetDataFromIDList gets all the file data directly from the PIDL, without accessing the disc at all. Microsoft's implementation of filesystem PIDLs stores quite a large amount of data in each SHITEMID (cf. my earlier suggestion), except for those unfortunate creation etc dates of course. This is an advantage since the cached information can be accessed quickly, but it has to be interpreted carefully. A PIDL you obtained yesterday won't necessarily contain accurate information, if for example the file was modified in the meantime. Still, even a stale PIDL is good enough to uniquely identify a file. To convince yourselves, take two PIDLs to the same file, obtained at different times, and see what CompareIDs will return.


Shell을 이용하여 디렉토리 정보등을 알아 올 때 알아야 할 것들을 알차게 설명해 놓았다.

How To Convert a File Path to an ITEMIDLIST

Windows 2007. 2. 6. 23:30 posted by deneb

How To Convert a File Path to an ITEMIDLIST

Article ID : 132750
Last Review : July 11, 2005
Revision : 1.3
This article was previously published under Q132750

SUMMARY

When developing an application that interacts with the Windows Explorer shell, you may need to convert an arbitrary path to a file to an ITEMIDLIST. You can do this using the IShellFolder::ParseDisplayName API.

MORE INFORMATION

Following is an example of how to use the IShellFolder interface to convert the path to the file Readme.txt in the current directory to an ITEMIDLIST. The example is written in C. If the program is written using Visual C++, accessing member functions through the lpVtbl variable is unnecessary.
   LPITEMIDLIST  pidl;
   LPSHELLFOLDER pDesktopFolder;
   char          szPath[MAX_PATH];
   OLECHAR       olePath[MAX_PATH];
   ULONG         chEaten;
   ULONG         dwAttributes;
   HRESULT       hr;

   // 
   // Get the path to the file we need to convert.
   // 
   GetCurrentDirectory(MAX_PATH, szPath);
   lstrcat(szPath, "\\readme.txt");

   // 
   // Get a pointer to the Desktop's IShellFolder interface.
   // 
   if (SUCCEEDED(SHGetDesktopFolder(&pDesktopFolder)))
   {
       // 
       // IShellFolder::ParseDisplayName requires the file name be in
       // Unicode.
       // 
       MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPath, -1,
                           olePath, MAX_PATH);

       // 
       // Convert the path to an ITEMIDLIST.
       // 
       hr = pDesktopFolder->lpVtbl->ParseDisplayName(pDesktopFolder,
                                                     NULL,
                                                     NULL,
                                                     olePath,
                                                     &chEaten,
                                                     &pidl,
                                                     &dwAttributes);
       if (FAILED(hr))
       {
           // Handle error.
       }

       // 
       // pidl now contains a pointer to an ITEMIDLIST for .\readme.txt.
       // This ITEMIDLIST needs to be freed using the IMalloc allocator
       // returned from SHGetMalloc().
       // 

       //release the desktop folder object
         pDesktopFolder->lpVtbl->Release();
   }
				

APPLIES TO
Microsoft Platform Software Development Kit-January 2000 Edition

ITEMIDLIST management library

Windows 2007. 2. 6. 23:18 posted by deneb
출처 : http://www.codeproject.com/shell/pxshlapi.asp

This library simplifies management of Windows Shell ITEMIDLISTs (further PIDLs). For me, it always has been trouble to keep track of all allocated PIDLs and to free them in time. So, I wrote this library.

As time goes, the library has became rather messy (it's because I put there all PIDL-related functions that may be reusable). But it still helps me a lot.

The core of this library is CPidl class. All other functions exported here are mostly supplemental.

Constructors

CPidl::CPidl()
Constructs empty CPidl instance
CPidl::CPidl(LPITEMIDLIST other)
Constructs CPidl instance and attaches (not copies) ITEMIDLIST allocated somewhere else. At destruction time attached ITEMIDLIST will be deallocated.
CPidl::CPidl(const CPidl& other)
Copy constructor. Copies one instance of CPidl into another.
CPidl::CPidl(LPCTSTR pszPath)
Constructs CPidl instance from file or folder path. In case of error, the PIDL will be empty. It uses IShellFolder::ParseDisplayName() for getting PIDL.
CPidl::CPidl(int nSpecialFolder)
Constructs CPidl instance from special folder ID. (See CSIDL_XXX constants in MSDN).

Member functions

LPITEMIDLIST CPidl::Detach()
Detaches contained PIDL from wrapper
LPITEMIDLIST CPidl::Copy()
returns a copy of contained PIDL
void CPidl::Free()
frees contained PIDL. This member function is called automatically at destruction time.
CPidl::operator bool()
conversion operator for using in boolean expressions. Will return true if contained PIDL is not NULL
CPidl::operator LPITEMIDLIST()
Useful conversion operator that allows to use CPidlas a function argument in place of LPITEMIDLIST
CPidl::operator LPITEMIDLIST*()
CPidl::operator LPCITEMIDLIST*()
Useful conversion operator that allows to use CPidl as a function argument in place of LPITEMIDLIST*. Usually the pointer to LPITEMIDLIST is used to receive when a PIDL from function. Make sure you call CPidl::Free() before using CPidl instance for receiving PIDLs!
CPidl& CPidl::operator=(LPITEMIDLIST other)
CPidl& CPidl::operator=(const CPidl& other)
Assignment operators

Global functions

IShellFolderPtr& GetDesktopFolder()
returns a reference to static instance of IShellFolder interface for root namespace folder.
IMallocPtr& GetMalloc()
returns a reference to static instance of IMalloc interface. This interface is essential for working with PIDLs.
int GetItemIDSize(LPCITEMIDLIST pidl)
returns PIDL size in bytes.
int GetItemIDCount(LPCITEMIDLIST pidl)
returns number of elements in PIDL. If you don't know what does it mean, reread "Working with Item ID Lists" article in MSDN.
LPBYTE GetItemIDPos(LPCITEMIDLIST pidl, int nPos)
gets pointer to nPos'th element in PIDL or NULL if nPos exceeds number of elements in PIDL.
LPITEMIDLIST CopyItemID(LPCITEMIDLIST pidl, int cb=-1)
makes a copy of PIDL. cb specifies number of bytes to copy. If it's equal -1, entire PIDL will be copied.
LPITEMIDLIST MergeItemID(LPCITEMIDLIST pidl,...)
Merges two or more PIDLs (usually relative ones) into absolute (or fully-qualified) PIDL. The programmer should know what he's doing when he calls this function :-). Typical usage is to make fully-qualified PIDL from folder PIDL and PIDL returned by IShellFolder::EnumObjects()
int CompareItemID(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
int CompareItemID(LPCITEMIDLIST pidl1,int nSpecialFolder)
int CompareItemID(int nSpecialFolder,LPCITEMIDLIST pidl2)
Compares two PIDLs. Returns 0 if equal and -1 otherwise.
LPITEMIDLIST GetItemIDFromPath(LPCTSTR pszPath)
returns PIDL for file or folder name. Or NULL if error
HRESULT SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, VOID **ppv, LPCITEMIDLIST *ppidlLast)
Closely resembles standard shell function SHBindToParent(). It was neccessary to write it becuase it's not available on Windows 95/NT. Refer to MSDN for arguments description.
BOOL TrackItemIDContextMenu(LPCITEMIDLIST pidlShellItem, UINT nFlags, LPPOINT ptPoint, HWND hWnd)
BOOL TrackItemIDContextMenu(LPCTSTR pszShellItemPath, UINT nFlags, LPPOINT ptPoint, HWND hWnd)
This function builds, shows and tracks shell context menu for PIDL or or file/folder path. It returns TRUE if user clicked on some context menu item. In case of error or if user didn't choose anything from menu it returns FALSE.
  • LPCITEMIDLIST pidlShellItem, LPCTSTR pszShellItemPath: a PIDL or path name of the shell item to show context menu for.
  • UINT nFlags: a set of TPM_XXX flags. See function TrackPopupMenu() for description
  • LPPOINT ptPoint: a point in screen coordinates where menu should appear.
  • HWND hWnd: a handle to the window - owner of the menu. It cannot be NULL

쉘을 다루는데 있어서 애로사항이 꽃피는 경우가 파다한데 그나마 쉽게 접근 할 수 있는 클래스

출처 : http://tunelinux.pe.kr/gboard/bbs/board.php?bo_table=tip&wr_id=75&page=

RHN 에 지식기반정보가 있습니다.
rhn 등록되어있는 사용자만이 접속할 수 있지요.

한번 테스팅해볼만한 내용이네요.
문제해결을 위하여.

그리고 시스템의 정보를 수집하기 위한 sysreport 라는 프로그램이 있습니다. rhn등을 이용하여 설치하면 되고 위 명령만 치면 시스템의 주요정보를 모읍니다.

Solution Found
Issue:
My system had a kernel panic, an oops message, or is freezing for no apparent reason. How can I find out what is causing this?
Resolution:         Last update: 08-17-04
Resolving a kernel panic or a kernel oops is not a simple task. First off, in order for Red Hat to understand the cause of this, we will need to see the panic or oops message in its entirety. Below you will find our \"Profiling\" document, it contains the information that Red Hat requires in order to best troubleshoot a kernel panic or kernel oops related to a system crash.

We do recommend that you are running the latest kernel available for your release version and that have your system completely updated.

To further debug this problem we will need the following information:
The output from the following commands:

    * sysreport
    * lspci -vv
    * lsmod
    * cat /proc/meminfo
    * cat /proc/cpuinfo
    * uname -a


Please note, sysreport is an application that may not be installed on your system. If you do not have it installed, please install the sysreport RPM in one of the following ways:

    * Run: up2date sysreport if your system is registered with RHN, this will download and install the package for you.
    * Locate the sysreport package on your installation CD's and install the package with: rpm -ivh sysreport-version#.rpm - where version# will match the files version number on your installation CD.


If possible, please run these commands when the slow down is occuring, or as close as possible to a reproduceable crash. That being said, we do recognize that this is not always possible, but the information is still needed.

    * OOPS messages:

      If your machine crashes with an OOPS message, similar to the following:

Unable to handle kernel NULL pointer dereference at virtual address
00000018
*pde = 0f992001
Oops: 0000
CPU:    1
EIP:    0010:[]    Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010207
eax: 00000000   ebx: c87a1ed0   ecx: c02de5e0   edx: f3de3b00
esi: c87a1eb4   edi: 00000000   ebp: 00000007   esp: c3f5bfa0
ds: 0018   es: 0018   ss: 0018
Process kswapd (pid: 11, stackpage=c3f5b000)
Stack: 00000000 fffffe5d 00000245 00085992 00000001 00000000 000000c0 000000c0
       0008e000 c0136c51 000000c0 00000000 c3f5a000 00000006 c0136ce5 000000c0
       00000000 00010f00 c3ff1fb8 c0105000 c0105866 00000000 c0136c90 c02f5fc0
Call Trace: [] do_try_to_free_pages [kernel] 0x11
[] kswapd [kernel] 0x55
[] stext [kernel] 0x0
[] kernel_thread [kernel] 0x26
[] kswapd [kernel] 0x0
Code: f7 40 18 06 00 00 00 75 f0 8b 40 28 39 d0 75 f0 31 d2 85 d2


>>EIP; c0136177    <=====

Trace; c0136c51
Trace; c0136ce5
Trace; c0105000 <_stext+0/0>
Trace; c0105866
Trace; c0136c90
Code;  c0136177
00000000 <_EIP>:
Code;  c0136177    <=====
   0:   f7 40 18 06 00 00 00      testl  $0x6,0x18(%eax)   <=====
Code;  c013617e
   7:   75 f0                     jne    fffffff9 <_EIP+0xfffffff9>
c0136170
Code;  c0136180
   9:   8b 40 28                  mov    0x28(%eax),%eax
Code;  c0136183
   c:   39 d0                     cmp    %edx,%eax
Code;  c0136185
   e:   75 f0                     jne    0 <_EIP>
Code;  c0136187
  10:   31 d2                     xor    %edx,%edx
Code;  c0136189
  12:   85 d2                     test   %edx,%edx


      We will need the full output from the OOPS message, which can be obtained in one of the following ways:

          o Copied down by hand (or from a digital picture), please remember we need the complete message and that this may sometimes be the only way to get the oops message.
          o Setting up a serial console to capture the message. This can be accomplished by connecting a null modem cable to the serial port of the machine and adding:

            console=ttyS0,115200 console=tty0

            to either the kernel line of grub or in an \"append=\" statement for lilo. Once this is done, on the other machine the null modem is attached to, run a terminal emulator such as \"minicom\" (linux) or \"hyperterminal\" (windows).

    * Mysterious Hangs, Freezes and Slowdowns:

      For hangs and freezes, we would like you to capture some information by enabling the sysrq key. This can be enabled by editing the file /etc/sysctl.conf and changing the line to read:

      kernel.sysrq = 1

      Enable it immediately by saving the file and running:

      # sysctl -p

      Once this is enabled, we will need the output from the following key combinations:
          o alt-sysrq-t
          o alt-sysrq-p
          o alt-sysrq-m
      * Please note that sysrq is the PrintScreen key.

      Please run alt-sysrq-p multiple times so that we can be sure to get output from all CPUs on the machine. Also, run alt-sysrq-m last as it has a possiblity of locking the box up harder then it already is. You may wish to use a serial console to capture the information. You will also want to ensure that we have at least 1 alt-sysrq-p from each CPU, denoted by a CPU: # line in the output. Note the first CPU is number 0.

    * Slowdowns:

      For general slowdowns we will first need to know the following:
          o What kind of load is the box under?
          o Are you running anything to produce this load?
          o If you stop running whatever may cause the load, does the slowness immediately go away?

            Next, we would like you to follow the following steps to gather some data for our engineers:

            1. Enable kernel profiling by turning on nmi_watchdog and allocating the kernel profile buffer. For example, add the following two items to the \"kernel\" line of /boot/grub/grub.conf (using grub):

                  profile=2 nmi_watchdog=1

            as in the following example:

                  kernel /vmlinuz-2.4.9-e.27smp ro profile=2 nmi_watchdog=1

            If using LILO, add the following to the global section (before the first image= line) of lilo.conf:
                  append=\"profile=2 nmi_watchdog=1\"
            and run lilo -v as root.
            Now you should be able to reboot.

            2. Create a shell script containing the following lines:

#!/bin/sh
while /bin/true; do
  echo;date
  /usr/sbin/readprofile -v -m /boot/System.map | sort -nr +2 | head -15
  /usr/sbin/readprofile -r
  sleep 5
done

          o Make the system demonstrate the aberrant behavior.
          o Run the following three commands simultaneously:

                  Execute the readprofile shell script above, redirecting its output to a file.
                  Execute vmstat 5 and redirect its output to a second file.
                  Execute top -d5 and redirect its output to a third file.

          o Attach the output files (preferably in gzip'd tar file format) to a web ticket that either you or a Red Hat Engineer has opened.


      You can open a web ticket with Red Hat support by logging into your www.redhat.com account in the Support and Docs section and selecting the Web Support button located under the \"Active Support Entitlements\" section.